From d997cde3878c08c3d525e4d04e56eacac7136a68 Mon Sep 17 00:00:00 2001 From: Samuel Tariku Date: Tue, 7 Oct 2025 13:39:36 +0300 Subject: [PATCH] fix: integration fixes --- db/migrations/000001_fortune.up.sql | 37 +- db/query/company.sql | 11 +- db/query/leagues.sql | 23 + docs/docs.go | 1879 ++++++++++++++--- docs/swagger.json | 1879 ++++++++++++++--- docs/swagger.yaml | 1233 +++++++++-- gen/db/company.sql.go | 31 +- gen/db/leagues.sql.go | 48 +- gen/db/models.go | 1 + gen/db/shop_transactions.sql.go | 15 +- internal/domain/company.go | 44 +- internal/domain/shop_bet.go | 3 + internal/domain/wallet.go | 9 +- internal/repository/bet.go | 7 +- internal/repository/common.go | 12 + internal/repository/company.go | 49 +- internal/repository/event.go | 14 +- internal/repository/league.go | 13 +- internal/repository/shop_bet.go | 5 +- internal/repository/user.go | 2 +- internal/repository/virtual_game.go | 56 +- internal/repository/wallet.go | 3 + internal/services/company/port.go | 2 +- internal/services/company/service.go | 2 +- internal/services/league/port.go | 2 +- internal/services/league/service.go | 4 +- internal/services/report/service.go | 10 +- internal/services/virtualGame/port.go | 2 +- internal/services/virtualGame/service.go | 6 +- internal/web_server/cron.go | 2 +- internal/web_server/handlers/admin.go | 42 +- .../web_server/handlers/company_handler.go | 24 +- internal/web_server/handlers/leagues.go | 4 +- internal/web_server/handlers/user.go | 6 +- 34 files changed, 4654 insertions(+), 826 deletions(-) create mode 100644 internal/repository/common.go diff --git a/db/migrations/000001_fortune.up.sql b/db/migrations/000001_fortune.up.sql index c2e98cb..0fd37cb 100644 --- a/db/migrations/000001_fortune.up.sql +++ b/db/migrations/000001_fortune.up.sql @@ -73,7 +73,8 @@ CREATE TABLE IF NOT EXISTS wallets ( is_active BOOLEAN NOT NULL DEFAULT true, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - UNIQUE(user_id, type) + UNIQUE(user_id, type), + CONSTRAINT balance_positve CHECK (balance >= 0) ); CREATE TABLE refresh_tokens ( id BIGSERIAL PRIMARY KEY, @@ -184,19 +185,19 @@ CREATE TABLE IF NOT EXISTS banks ( currency VARCHAR(10) NOT NULL, bank_logo TEXT -- URL or base64 string ); -CREATE TABLE IF NOT EXISTS wallets ( - id BIGSERIAL PRIMARY KEY, - balance BIGINT NOT NULL DEFAULT 0, - is_withdraw BOOLEAN NOT NULL, - is_bettable BOOLEAN NOT NULL, - is_transferable BOOLEAN NOT NULL, - user_id BIGINT NOT NULL, - type VARCHAR(255) NOT NULL, - is_active BOOLEAN NOT NULL DEFAULT true, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - CONSTRAINT balance_positve CHECK (balance >= 0) -); +-- CREATE TABLE IF NOT EXISTS wallets ( +-- id BIGSERIAL PRIMARY KEY, +-- balance BIGINT NOT NULL DEFAULT 0, +-- is_withdraw BOOLEAN NOT NULL, +-- is_bettable BOOLEAN NOT NULL, +-- is_transferable BOOLEAN NOT NULL, +-- user_id BIGINT NOT NULL, +-- type VARCHAR(255) NOT NULL, +-- is_active BOOLEAN NOT NULL DEFAULT true, +-- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, +-- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, +-- CONSTRAINT balance_positve CHECK (balance >= 0) +-- ); CREATE TABLE IF NOT EXISTS customer_wallets ( id BIGSERIAL PRIMARY KEY, customer_id BIGINT NOT NULL, @@ -270,7 +271,7 @@ CREATE TABLE IF NOT EXISTS branches ( name VARCHAR(255) NOT NULL, location TEXT NOT NULL, profit_percent REAL NOT NULL, - is_active BOOLEAN NOT NULL DEFAULT false, + is_active BOOLEAN NOT NULL DEFAULT true, wallet_id BIGINT NOT NULL, branch_manager_id BIGINT NOT NULL, company_id BIGINT NOT NULL, @@ -406,7 +407,7 @@ CREATE TABLE companies ( admin_id BIGINT NOT NULL, wallet_id BIGINT NOT NULL, deducted_percentage REAL NOT NULL, - is_active BOOLEAN NOT NULL DEFAULT false, + is_active BOOLEAN NOT NULL DEFAULT true, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT deducted_percentage_check CHECK ( @@ -642,6 +643,7 @@ SELECT sb.*, st.verified AS transaction_verified, bets.status, bets.total_odds, + bets.fast_code, JSON_AGG (bet_outcomes.*) AS outcomes FROM shop_bets AS sb JOIN shop_transactions st ON st.id = sb.shop_transaction_id @@ -655,7 +657,8 @@ GROUP BY sb.id, st.amount, st.verified, bets.status, - bets.total_odds; + bets.total_odds, + bets.fast_code; CREATE VIEW shop_deposit_detail AS SELECT sd.*, st.full_name, diff --git a/db/query/company.sql b/db/query/company.sql index 516775f..4f5952c 100644 --- a/db/query/company.sql +++ b/db/query/company.sql @@ -4,9 +4,10 @@ INSERT INTO companies ( slug, admin_id, wallet_id, - deducted_percentage + deducted_percentage, + is_active ) -VALUES ($1, $2, $3, $4, $5) +VALUES ($1, $2, $3, $4, $5, $6) RETURNING *; -- name: GetAllCompanies :many SELECT * @@ -38,7 +39,7 @@ WHERE slug = $1; SELECT * FROM companies_details WHERE name ILIKE '%' || $1 || '%'; --- name: UpdateCompany :one +-- name: UpdateCompany :exec UPDATE companies SET name = COALESCE(sqlc.narg(name), name), admin_id = COALESCE(sqlc.narg(admin_id), admin_id), @@ -47,9 +48,9 @@ SET name = COALESCE(sqlc.narg(name), name), sqlc.narg(deducted_percentage), deducted_percentage ), + slug = COALESCE(sqlc.narg(slug), slug), updated_at = CURRENT_TIMESTAMP -WHERE id = $1 -RETURNING *; +WHERE id = $1; -- name: DeleteCompany :exec DELETE FROM companies WHERE id = $1; \ No newline at end of file diff --git a/db/query/leagues.sql b/db/query/leagues.sql index b45460f..047ce5d 100644 --- a/db/query/leagues.sql +++ b/db/query/leagues.sql @@ -40,8 +40,31 @@ WHERE ( name ILIKE '%' || sqlc.narg('query') || '%' OR sqlc.narg('query') IS NULL ) + AND ( + default_is_active = sqlc.narg('is_active') + OR sqlc.narg('is_active') IS NULL + ) ORDER BY name ASC LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset'); +-- name: GetTotalLeagues :one +SELECT COUNT(*) +FROM leagues +WHERE ( + 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 ( + name ILIKE '%' || sqlc.narg('query') || '%' + OR sqlc.narg('query') IS NULL + ) + AND ( + default_is_active = sqlc.narg('is_active') + OR sqlc.narg('is_active') IS NULL + ); -- name: GetTotalLeaguesWithSettings :one SELECT COUNT(*) FROM leagues l diff --git a/docs/docs.go b/docs/docs.go index a7f73c8..3114939 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -125,7 +125,7 @@ const docTemplate = `{ } }, "post": { - "description": "Create Admin", + "description": "Create transaction approver", "consumes": [ "application/json" ], @@ -135,15 +135,15 @@ const docTemplate = `{ "tags": [ "admin" ], - "summary": "Create Admin", + "summary": "Create transaction approver", "parameters": [ { - "description": "Create admin", + "description": "Create transaction approver", "name": "manger", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/handlers.CreateAdminReq" + "$ref": "#/definitions/handlers.CreateTransactionApproverReq" } } ], @@ -800,6 +800,47 @@ const docTemplate = `{ } } }, + "/api/v1/atlas/games": { + "get": { + "description": "Retrieves available Atlas virtual games from the provider", + "produces": [ + "application/json" + ], + "tags": [ + "Virtual Games - Atlas" + ], + "summary": "List Atlas virtual games", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.AtlasGameEntity" + } + } + } + } + ] + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/atlas/init-game": { "post": { "description": "Initializes a game session for the given player using Atlas virtual game provider", @@ -1613,6 +1654,50 @@ const docTemplate = `{ } } }, + "/api/v1/branch/{id}/return": { + "post": { + "description": "Unassign the branch wallet to company", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "branch" + ], + "summary": "Unassign the branch wallet to company", + "parameters": [ + { + "type": "integer", + "description": "Branch ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.BranchDetailRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/branchCashier": { "get": { "description": "Gets branch for cahier", @@ -2751,6 +2836,56 @@ const docTemplate = `{ } } }, + "/api/v1/customer/{id}/bets": { + "get": { + "description": "Get customer bets", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "customer" + ], + "summary": "Get customer bets", + "parameters": [ + { + "type": "integer", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.CustomersRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/customerWallet": { "get": { "description": "Retrieve all customer wallets", @@ -2913,6 +3048,182 @@ const docTemplate = `{ } } }, + "/api/v1/enetpulse/sports": { + "get": { + "description": "Fetches all sports stored in the database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "EnetPulse - Sports" + ], + "summary": "Get all sports", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.EnetpulseSport" + } + } + } + } + ] + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, + "/api/v1/enetpulse/tournament-stages": { + "get": { + "description": "Fetches all tournament stages stored in the database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "EnetPulse - Tournament Stages" + ], + "summary": "Get all tournament stages", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.EnetpulseTournamentStage" + } + } + } + } + ] + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, + "/api/v1/enetpulse/tournament-templates": { + "get": { + "description": "Fetches all tournament templates stored in the database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "EnetPulse - Tournament Templates" + ], + "summary": "Get all tournament templates", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.EnetpulseTournamentTemplate" + } + } + } + } + ] + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, + "/api/v1/enetpulse/tournaments": { + "get": { + "description": "Fetches all tournaments stored in the database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "EnetPulse - Tournaments" + ], + "summary": "Get all tournaments", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.EnetpulseTournament" + } + } + } + } + ] + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/events": { "get": { "description": "Retrieve all upcoming events from the database", @@ -3075,6 +3386,138 @@ const docTemplate = `{ } } }, + "/api/v1/events/{id}/bets": { + "get": { + "description": "Retrieve bet outcomes by event id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "prematch" + ], + "summary": "Retrieve bet outcomes by event id", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.BaseEvent" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/events/{id}/is_monitored": { + "patch": { + "description": "Update the event is_monitored", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "event" + ], + "summary": "update the event is_monitored", + "parameters": [ + { + "type": "integer", + "description": "Event ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/events/{id}/settings": { + "put": { + "description": "Update the event settings", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "event" + ], + "summary": "update the event settings", + "parameters": [ + { + "type": "integer", + "description": "Event ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/issues": { "get": { "description": "Admin endpoint to list all reported issues with pagination", @@ -3681,6 +4124,108 @@ const docTemplate = `{ } } }, + "/api/v1/odds/pre-match": { + "get": { + "description": "Fetches pre-match odds from EnetPulse for a given event", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "EnetPulse - PreMatch" + ], + "summary": "Get pre-match odds for an event", + "parameters": [ + { + "type": "integer", + "description": "Event ID", + "name": "objectFK", + "in": "query", + "required": true + }, + { + "type": "array", + "items": { + "type": "integer" + }, + "collectionFormat": "csv", + "description": "Odds provider IDs (comma separated)", + "name": "oddsProviderFK", + "in": "query" + }, + { + "type": "integer", + "description": "Outcome type ID", + "name": "outcomeTypeFK", + "in": "query" + }, + { + "type": "integer", + "description": "Outcome scope ID", + "name": "outcomeScopeFK", + "in": "query" + }, + { + "type": "integer", + "description": "Outcome subtype ID", + "name": "outcomeSubtypeFK", + "in": "query" + }, + { + "type": "integer", + "description": "Limit results", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Offset results", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "description": "Language type ID", + "name": "languageTypeFK", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/domain.PreMatchOddsResponse" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/odds/upcoming/{upcoming_id}": { "get": { "description": "Retrieve prematch odds by upcoming event ID (FI from Bet365) with optional pagination", @@ -3916,147 +4461,6 @@ const docTemplate = `{ } } }, - "/api/v1/referral/settings": { - "get": { - "security": [ - { - "Bearer": [] - } - ], - "description": "Retrieves current referral settings (admin only)", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "referral" - ], - "summary": "Get referral settings", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/domain.ReferralSettings" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "403": { - "description": "Forbidden", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - } - } - }, - "put": { - "security": [ - { - "Bearer": [] - } - ], - "description": "Updates referral settings (admin only)", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "referral" - ], - "summary": "Update referral settings", - "parameters": [ - { - "description": "Referral settings", - "name": "settings", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/domain.ReferralSettings" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "403": { - "description": "Forbidden", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - } - } - } - }, - "/api/v1/referral/stats": { - "get": { - "security": [ - { - "Bearer": [] - } - ], - "description": "Retrieves referral statistics for the authenticated user", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "referral" - ], - "summary": "Get referral statistics", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/domain.ReferralStats" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - } - } - } - }, "/api/v1/report-files/download/{filename}": { "get": { "description": "Downloads a generated report CSV file from the server", @@ -4248,7 +4652,7 @@ const docTemplate = `{ } } }, - "/api/v1/result/{id}": { + "/api/v1/result/b365/{id}": { "get": { "description": "Get results for an event", "consumes": [ @@ -5128,6 +5532,92 @@ const docTemplate = `{ } } }, + "/api/v1/sport/bet/{id}": { + "get": { + "description": "Gets a single bet by id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "bet" + ], + "summary": "Gets bet by id", + "parameters": [ + { + "type": "integer", + "description": "Bet ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.BetRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + }, + "delete": { + "description": "Deletes bet by id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "bet" + ], + "summary": "Deletes bet by id", + "parameters": [ + { + "type": "integer", + "description": "Bet ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/super-login": { "post": { "description": "Login super-admin", @@ -5262,6 +5752,161 @@ const docTemplate = `{ } } }, + "/api/v1/t-approver": { + "get": { + "description": "Get all Admins", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Get all Admins", + "parameters": [ + { + "type": "integer", + "description": "Page number", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "Page size", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.AdminRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/t-approver/{id}": { + "get": { + "description": "Get a single admin by id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Get admin by id", + "parameters": [ + { + "type": "integer", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.AdminRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + }, + "put": { + "description": "Update Admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Update Admin", + "parameters": [ + { + "description": "Update Admin", + "name": "admin", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.updateAdminReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/telebirr/callback": { "post": { "description": "Processes the Telebirr payment result and updates wallet balance.", @@ -5354,6 +5999,385 @@ const docTemplate = `{ } } }, + "/api/v1/tenant": { + "get": { + "description": "Check if phone number or email exist", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Check if phone number or email exist", + "parameters": [ + { + "description": "Check phone number or email exist", + "name": "checkPhoneEmailExist", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.CheckPhoneEmailExistReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.CheckPhoneEmailExistRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/customer": { + "get": { + "description": "Get all Customers", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "customer" + ], + "summary": "Get all Customers", + "parameters": [ + { + "type": "integer", + "description": "Page number", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "Page size", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.CustomersRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/customer/{id}": { + "get": { + "description": "Get a single customer by id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "customer" + ], + "summary": "Get customer by id", + "parameters": [ + { + "type": "integer", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.CustomersRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + }, + "put": { + "description": "Update Customers", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "customer" + ], + "summary": "Update Customers", + "parameters": [ + { + "description": "Update Customers", + "name": "Customers", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.updateCustomerReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/customer/{id}/bets": { + "get": { + "description": "Get tenant customer bets", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "customer" + ], + "summary": "Get tenant customer bets", + "parameters": [ + { + "type": "integer", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.CustomersRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/events/{id}/bets": { + "get": { + "description": "Retrieve bet outcomes by event id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "prematch" + ], + "summary": "Retrieve bet outcomes by event id", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.BaseEvent" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/events/{id}/settings": { + "put": { + "description": "Update the event settings", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "event" + ], + "summary": "update the event settings", + "parameters": [ + { + "type": "integer", + "description": "Event ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/referral/stats": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "Retrieves referral statistics for the authenticated user", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "referral" + ], + "summary": "Get referral statistics", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.ReferralStats" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/transfer/refill/:id": { "post": { "description": "Super Admin route to refill a wallet", @@ -5536,6 +6560,144 @@ const docTemplate = `{ } } }, + "/api/v1/user/resetPassword": { + "post": { + "description": "Reset password", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Reset password", + "parameters": [ + { + "description": "Reset password", + "name": "resetPassword", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.ResetPasswordReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/user/search": { + "post": { + "description": "Search for user using name or phone", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Search for user using name or phone", + "parameters": [ + { + "description": "Search for using his name or phone", + "name": "searchUserByNameOrPhone", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.SearchUserByNameOrPhoneReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.UserProfileRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/user/sendResetCode": { + "post": { + "description": "Send reset code", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Send reset code", + "parameters": [ + { + "description": "Send reset code", + "name": "resetCode", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.ResetCodeReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/user/single/{id}": { "get": { "description": "Get a single user by id", @@ -6702,50 +7864,6 @@ const docTemplate = `{ } } }, - "/api/v1/{tenant_slug}/events/{id}/settings": { - "put": { - "description": "Update the event settings", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "event" - ], - "summary": "update the event settings", - "parameters": [ - { - "type": "integer", - "description": "Event ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - } - } - } - }, "/api/v1/{tenant_slug}/leagues": { "get": { "description": "Gets all leagues", @@ -7760,7 +8878,7 @@ const docTemplate = `{ }, "/api/v1/{tenant_slug}/user/resetPassword": { "post": { - "description": "Reset password", + "description": "Reset tenant password", "consumes": [ "application/json" ], @@ -7770,7 +8888,7 @@ const docTemplate = `{ "tags": [ "user" ], - "summary": "Reset password", + "summary": "Reset tenant password", "parameters": [ { "description": "Reset password", @@ -8590,6 +9708,40 @@ const docTemplate = `{ } } }, + "domain.AtlasGameEntity": { + "type": "object", + "properties": { + "demo_url": { + "description": "✅ new field", + "type": "string" + }, + "deviceType": { + "type": "string" + }, + "game_id": { + "type": "string" + }, + "hasFreeBets": { + "type": "boolean" + }, + "has_demo": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "providerId": { + "type": "string" + }, + "thumbnail_img_url": { + "description": "✅ new field", + "type": "string" + }, + "type": { + "type": "string" + } + } + }, "domain.AtlasGameInitRequest": { "type": "object", "properties": { @@ -8733,7 +9885,7 @@ const docTemplate = `{ "type": "string" }, "id": { - "type": "string" + "type": "integer" }, "isLive": { "type": "boolean" @@ -8765,6 +9917,9 @@ const docTemplate = `{ "source": { "$ref": "#/definitions/domain.EventSource" }, + "sourceEventID": { + "type": "string" + }, "sportID": { "type": "integer" }, @@ -9347,9 +10502,15 @@ const docTemplate = `{ "type": "number", "example": 0.1 }, + "is_active": { + "type": "boolean" + }, "name": { "type": "string", "example": "CompanyName" + }, + "slug": { + "type": "string" } } }, @@ -9591,6 +10752,172 @@ const docTemplate = `{ } } }, + "domain.EnetpulseSport": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "description": "DB primary key", + "type": "integer" + }, + "last_updated_at": { + "type": "string" + }, + "name": { + "description": "from API \"name\"", + "type": "string" + }, + "sport_id": { + "description": "from API \"id\"", + "type": "string" + }, + "status": { + "description": "active/inactive", + "type": "integer" + }, + "updated_at": { + "type": "string" + }, + "updates_count": { + "description": "from API \"n\"", + "type": "integer" + } + } + }, + "domain.EnetpulseTournament": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "description": "internal DB PK", + "type": "integer" + }, + "lastUpdatedAt": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "type": "integer" + }, + "tournamentID": { + "type": "string" + }, + "tournamentTemplateFK": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "updatesCount": { + "type": "integer" + } + } + }, + "domain.EnetpulseTournamentStage": { + "type": "object", + "properties": { + "country_fk": { + "description": "country FK from API", + "type": "string" + }, + "country_name": { + "description": "country name from API", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "end_date": { + "description": "end date/time", + "type": "string" + }, + "gender": { + "description": "male/female/mixed/unknown", + "type": "string" + }, + "id": { + "type": "integer" + }, + "last_updated_at": { + "description": "ut from API", + "type": "string" + }, + "name": { + "description": "API name", + "type": "string" + }, + "stage_id": { + "description": "API id", + "type": "string" + }, + "start_date": { + "description": "start date/time", + "type": "string" + }, + "status": { + "description": "active/inactive", + "type": "integer" + }, + "tournament_fk": { + "description": "Foreign key to tournament", + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "updates_count": { + "description": "n from API", + "type": "integer" + } + } + }, + "domain.EnetpulseTournamentTemplate": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "gender": { + "description": "male, female, mixed, unknown", + "type": "string" + }, + "id": { + "type": "integer" + }, + "last_updated_at": { + "type": "string" + }, + "name": { + "description": "from API \"name\"", + "type": "string" + }, + "sport_fk": { + "description": "related sport id", + "type": "string" + }, + "status": { + "description": "optional", + "type": "integer" + }, + "template_id": { + "description": "from API \"id\"", + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "updates_count": { + "description": "from API \"n\"", + "type": "integer" + } + } + }, "domain.ErrorResponse": { "type": "object", "properties": { @@ -9667,6 +10994,15 @@ const docTemplate = `{ "away_team_image": { "type": "string" }, + "default_is_active": { + "type": "boolean" + }, + "default_is_featured": { + "type": "boolean" + }, + "default_winning_upper_limit": { + "type": "integer" + }, "fetched_at": { "type": "string" }, @@ -9680,7 +11016,7 @@ const docTemplate = `{ "type": "string" }, "id": { - "type": "string" + "type": "integer" }, "is_active": { "type": "boolean" @@ -9718,6 +11054,9 @@ const docTemplate = `{ "source": { "$ref": "#/definitions/domain.EventSource" }, + "source_event_id": { + "type": "string" + }, "sport_id": { "type": "integer" }, @@ -10344,11 +11683,17 @@ const docTemplate = `{ "domain.OddMarketWithEventFilter": { "type": "object", "properties": { + "isLive": { + "$ref": "#/definitions/domain.ValidBool" + }, "limit": { "$ref": "#/definitions/domain.ValidInt32" }, "offset": { "$ref": "#/definitions/domain.ValidInt32" + }, + "status": { + "$ref": "#/definitions/domain.ValidString" } } }, @@ -10517,6 +11862,41 @@ const docTemplate = `{ } } }, + "domain.PreMatchOddsResponse": { + "type": "object", + "properties": { + "eventFK": { + "description": "Define fields according to the Enetpulse preodds response structure\nExample:", + "type": "integer" + }, + "odds": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.PreMatchOutcome" + } + } + } + }, + "domain.PreMatchOutcome": { + "type": "object", + "properties": { + "oddsProviderFK": { + "type": "integer" + }, + "oddsValue": { + "type": "number" + }, + "outcomeFK": { + "type": "integer" + }, + "outcomeTypeFK": { + "type": "integer" + }, + "outcomeValue": { + "type": "string" + } + } + }, "domain.ProviderRequest": { "type": "object", "properties": { @@ -10603,55 +11983,14 @@ const docTemplate = `{ } } }, - "domain.ReferralSettings": { - "type": "object", - "properties": { - "betReferralBonusPercentage": { - "type": "number" - }, - "cashbackPercentage": { - "type": "number" - }, - "createdAt": { - "type": "string" - }, - "expiresAfterDays": { - "type": "integer" - }, - "id": { - "type": "integer" - }, - "maxReferrals": { - "type": "integer" - }, - "referralRewardAmount": { - "type": "number" - }, - "updatedAt": { - "type": "string" - }, - "updatedBy": { - "type": "string" - }, - "version": { - "type": "integer" - } - } - }, "domain.ReferralStats": { "type": "object", "properties": { - "completedReferrals": { - "type": "integer" - }, - "pendingRewards": { - "type": "number" - }, "totalReferrals": { "type": "integer" }, "totalRewardEarned": { - "type": "number" + "type": "integer" } } }, @@ -10713,14 +12052,16 @@ const docTemplate = `{ "admin", "branch_manager", "customer", - "cashier" + "cashier", + "transaction_approver" ], "x-enum-varnames": [ "RoleSuperAdmin", "RoleAdmin", "RoleBranchManager", "RoleCustomer", - "RoleCashier" + "RoleCashier", + "RoleTransactionApprover" ] }, "domain.RollbackRequest": { @@ -10955,6 +12296,10 @@ const docTemplate = `{ "type": "string", "example": "2025-04-08T12:00:00Z" }, + "fast_code": { + "type": "string", + "example": "12SD1" + }, "full_name": { "type": "string", "example": "John" @@ -11362,6 +12707,9 @@ const docTemplate = `{ "category": { "type": "string" }, + "demoUrl": { + "type": "string" + }, "deviceType": { "type": "string" }, @@ -11415,6 +12763,9 @@ const docTemplate = `{ "name": { "type": "string", "example": "CompanyName" + }, + "slug": { + "type": "string" } } }, @@ -11427,6 +12778,17 @@ const docTemplate = `{ } } }, + "domain.ValidBool": { + "type": "object", + "properties": { + "valid": { + "type": "boolean" + }, + "value": { + "type": "boolean" + } + } + }, "domain.ValidInt": { "type": "object", "properties": { @@ -11748,6 +13110,35 @@ const docTemplate = `{ } } }, + "handlers.CreateTransactionApproverReq": { + "type": "object", + "properties": { + "company_id": { + "type": "integer", + "example": 1 + }, + "email": { + "type": "string", + "example": "john.doe@example.com" + }, + "first_name": { + "type": "string", + "example": "John" + }, + "last_name": { + "type": "string", + "example": "Doe" + }, + "password": { + "type": "string", + "example": "password123" + }, + "phone_number": { + "type": "string", + "example": "1234567890" + } + } + }, "handlers.CreateTransferReq": { "type": "object", "properties": { @@ -11869,6 +13260,12 @@ const docTemplate = `{ "handlers.CustomersRes": { "type": "object", "properties": { + "company_id": { + "type": "integer" + }, + "company_name": { + "type": "string" + }, "created_at": { "type": "string" }, @@ -12050,7 +13447,7 @@ const docTemplate = `{ "type": "string", "example": "1234567890" }, - "referal_code": { + "referral_code": { "type": "string", "example": "ABC123" } @@ -12513,10 +13910,6 @@ const docTemplate = `{ "handlers.updateCustomerReq": { "type": "object", "properties": { - "company_id": { - "type": "integer", - "example": 1 - }, "first_name": { "type": "string", "example": "John" diff --git a/docs/swagger.json b/docs/swagger.json index 672b70e..bae0014 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -117,7 +117,7 @@ } }, "post": { - "description": "Create Admin", + "description": "Create transaction approver", "consumes": [ "application/json" ], @@ -127,15 +127,15 @@ "tags": [ "admin" ], - "summary": "Create Admin", + "summary": "Create transaction approver", "parameters": [ { - "description": "Create admin", + "description": "Create transaction approver", "name": "manger", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/handlers.CreateAdminReq" + "$ref": "#/definitions/handlers.CreateTransactionApproverReq" } } ], @@ -792,6 +792,47 @@ } } }, + "/api/v1/atlas/games": { + "get": { + "description": "Retrieves available Atlas virtual games from the provider", + "produces": [ + "application/json" + ], + "tags": [ + "Virtual Games - Atlas" + ], + "summary": "List Atlas virtual games", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.AtlasGameEntity" + } + } + } + } + ] + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/atlas/init-game": { "post": { "description": "Initializes a game session for the given player using Atlas virtual game provider", @@ -1605,6 +1646,50 @@ } } }, + "/api/v1/branch/{id}/return": { + "post": { + "description": "Unassign the branch wallet to company", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "branch" + ], + "summary": "Unassign the branch wallet to company", + "parameters": [ + { + "type": "integer", + "description": "Branch ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.BranchDetailRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/branchCashier": { "get": { "description": "Gets branch for cahier", @@ -2743,6 +2828,56 @@ } } }, + "/api/v1/customer/{id}/bets": { + "get": { + "description": "Get customer bets", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "customer" + ], + "summary": "Get customer bets", + "parameters": [ + { + "type": "integer", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.CustomersRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/customerWallet": { "get": { "description": "Retrieve all customer wallets", @@ -2905,6 +3040,182 @@ } } }, + "/api/v1/enetpulse/sports": { + "get": { + "description": "Fetches all sports stored in the database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "EnetPulse - Sports" + ], + "summary": "Get all sports", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.EnetpulseSport" + } + } + } + } + ] + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, + "/api/v1/enetpulse/tournament-stages": { + "get": { + "description": "Fetches all tournament stages stored in the database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "EnetPulse - Tournament Stages" + ], + "summary": "Get all tournament stages", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.EnetpulseTournamentStage" + } + } + } + } + ] + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, + "/api/v1/enetpulse/tournament-templates": { + "get": { + "description": "Fetches all tournament templates stored in the database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "EnetPulse - Tournament Templates" + ], + "summary": "Get all tournament templates", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.EnetpulseTournamentTemplate" + } + } + } + } + ] + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, + "/api/v1/enetpulse/tournaments": { + "get": { + "description": "Fetches all tournaments stored in the database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "EnetPulse - Tournaments" + ], + "summary": "Get all tournaments", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.EnetpulseTournament" + } + } + } + } + ] + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/events": { "get": { "description": "Retrieve all upcoming events from the database", @@ -3067,6 +3378,138 @@ } } }, + "/api/v1/events/{id}/bets": { + "get": { + "description": "Retrieve bet outcomes by event id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "prematch" + ], + "summary": "Retrieve bet outcomes by event id", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.BaseEvent" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/events/{id}/is_monitored": { + "patch": { + "description": "Update the event is_monitored", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "event" + ], + "summary": "update the event is_monitored", + "parameters": [ + { + "type": "integer", + "description": "Event ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/events/{id}/settings": { + "put": { + "description": "Update the event settings", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "event" + ], + "summary": "update the event settings", + "parameters": [ + { + "type": "integer", + "description": "Event ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/issues": { "get": { "description": "Admin endpoint to list all reported issues with pagination", @@ -3673,6 +4116,108 @@ } } }, + "/api/v1/odds/pre-match": { + "get": { + "description": "Fetches pre-match odds from EnetPulse for a given event", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "EnetPulse - PreMatch" + ], + "summary": "Get pre-match odds for an event", + "parameters": [ + { + "type": "integer", + "description": "Event ID", + "name": "objectFK", + "in": "query", + "required": true + }, + { + "type": "array", + "items": { + "type": "integer" + }, + "collectionFormat": "csv", + "description": "Odds provider IDs (comma separated)", + "name": "oddsProviderFK", + "in": "query" + }, + { + "type": "integer", + "description": "Outcome type ID", + "name": "outcomeTypeFK", + "in": "query" + }, + { + "type": "integer", + "description": "Outcome scope ID", + "name": "outcomeScopeFK", + "in": "query" + }, + { + "type": "integer", + "description": "Outcome subtype ID", + "name": "outcomeSubtypeFK", + "in": "query" + }, + { + "type": "integer", + "description": "Limit results", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Offset results", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "description": "Language type ID", + "name": "languageTypeFK", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/domain.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/domain.PreMatchOddsResponse" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + }, + "502": { + "description": "Bad Gateway", + "schema": { + "$ref": "#/definitions/domain.ErrorResponse" + } + } + } + } + }, "/api/v1/odds/upcoming/{upcoming_id}": { "get": { "description": "Retrieve prematch odds by upcoming event ID (FI from Bet365) with optional pagination", @@ -3908,147 +4453,6 @@ } } }, - "/api/v1/referral/settings": { - "get": { - "security": [ - { - "Bearer": [] - } - ], - "description": "Retrieves current referral settings (admin only)", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "referral" - ], - "summary": "Get referral settings", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/domain.ReferralSettings" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "403": { - "description": "Forbidden", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - } - } - }, - "put": { - "security": [ - { - "Bearer": [] - } - ], - "description": "Updates referral settings (admin only)", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "referral" - ], - "summary": "Update referral settings", - "parameters": [ - { - "description": "Referral settings", - "name": "settings", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/domain.ReferralSettings" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "403": { - "description": "Forbidden", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - } - } - } - }, - "/api/v1/referral/stats": { - "get": { - "security": [ - { - "Bearer": [] - } - ], - "description": "Retrieves referral statistics for the authenticated user", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "referral" - ], - "summary": "Get referral statistics", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/domain.ReferralStats" - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - } - } - } - }, "/api/v1/report-files/download/{filename}": { "get": { "description": "Downloads a generated report CSV file from the server", @@ -4240,7 +4644,7 @@ } } }, - "/api/v1/result/{id}": { + "/api/v1/result/b365/{id}": { "get": { "description": "Get results for an event", "consumes": [ @@ -5120,6 +5524,92 @@ } } }, + "/api/v1/sport/bet/{id}": { + "get": { + "description": "Gets a single bet by id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "bet" + ], + "summary": "Gets bet by id", + "parameters": [ + { + "type": "integer", + "description": "Bet ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.BetRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + }, + "delete": { + "description": "Deletes bet by id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "bet" + ], + "summary": "Deletes bet by id", + "parameters": [ + { + "type": "integer", + "description": "Bet ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/super-login": { "post": { "description": "Login super-admin", @@ -5254,6 +5744,161 @@ } } }, + "/api/v1/t-approver": { + "get": { + "description": "Get all Admins", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Get all Admins", + "parameters": [ + { + "type": "integer", + "description": "Page number", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "Page size", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.AdminRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/t-approver/{id}": { + "get": { + "description": "Get a single admin by id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Get admin by id", + "parameters": [ + { + "type": "integer", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.AdminRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + }, + "put": { + "description": "Update Admin", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "admin" + ], + "summary": "Update Admin", + "parameters": [ + { + "description": "Update Admin", + "name": "admin", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.updateAdminReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/telebirr/callback": { "post": { "description": "Processes the Telebirr payment result and updates wallet balance.", @@ -5346,6 +5991,385 @@ } } }, + "/api/v1/tenant": { + "get": { + "description": "Check if phone number or email exist", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Check if phone number or email exist", + "parameters": [ + { + "description": "Check phone number or email exist", + "name": "checkPhoneEmailExist", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.CheckPhoneEmailExistReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.CheckPhoneEmailExistRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/customer": { + "get": { + "description": "Get all Customers", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "customer" + ], + "summary": "Get all Customers", + "parameters": [ + { + "type": "integer", + "description": "Page number", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "Page size", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.CustomersRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/customer/{id}": { + "get": { + "description": "Get a single customer by id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "customer" + ], + "summary": "Get customer by id", + "parameters": [ + { + "type": "integer", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.CustomersRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + }, + "put": { + "description": "Update Customers", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "customer" + ], + "summary": "Update Customers", + "parameters": [ + { + "description": "Update Customers", + "name": "Customers", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.updateCustomerReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/customer/{id}/bets": { + "get": { + "description": "Get tenant customer bets", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "customer" + ], + "summary": "Get tenant customer bets", + "parameters": [ + { + "type": "integer", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.CustomersRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/events/{id}/bets": { + "get": { + "description": "Retrieve bet outcomes by event id", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "prematch" + ], + "summary": "Retrieve bet outcomes by event id", + "parameters": [ + { + "type": "string", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.BaseEvent" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/events/{id}/settings": { + "put": { + "description": "Update the event settings", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "event" + ], + "summary": "update the event settings", + "parameters": [ + { + "type": "integer", + "description": "Event ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/tenant/{tenant_slug}/referral/stats": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "Retrieves referral statistics for the authenticated user", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "referral" + ], + "summary": "Get referral statistics", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/domain.ReferralStats" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/transfer/refill/:id": { "post": { "description": "Super Admin route to refill a wallet", @@ -5528,6 +6552,144 @@ } } }, + "/api/v1/user/resetPassword": { + "post": { + "description": "Reset password", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Reset password", + "parameters": [ + { + "description": "Reset password", + "name": "resetPassword", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.ResetPasswordReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/user/search": { + "post": { + "description": "Search for user using name or phone", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Search for user using name or phone", + "parameters": [ + { + "description": "Search for using his name or phone", + "name": "searchUserByNameOrPhone", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.SearchUserByNameOrPhoneReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handlers.UserProfileRes" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, + "/api/v1/user/sendResetCode": { + "post": { + "description": "Send reset code", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "user" + ], + "summary": "Send reset code", + "parameters": [ + { + "description": "Send reset code", + "name": "resetCode", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handlers.ResetCodeReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.APIResponse" + } + } + } + } + }, "/api/v1/user/single/{id}": { "get": { "description": "Get a single user by id", @@ -6694,50 +7856,6 @@ } } }, - "/api/v1/{tenant_slug}/events/{id}/settings": { - "put": { - "description": "Update the event settings", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "event" - ], - "summary": "update the event settings", - "parameters": [ - { - "type": "integer", - "description": "Event ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/response.APIResponse" - } - } - } - } - }, "/api/v1/{tenant_slug}/leagues": { "get": { "description": "Gets all leagues", @@ -7752,7 +8870,7 @@ }, "/api/v1/{tenant_slug}/user/resetPassword": { "post": { - "description": "Reset password", + "description": "Reset tenant password", "consumes": [ "application/json" ], @@ -7762,7 +8880,7 @@ "tags": [ "user" ], - "summary": "Reset password", + "summary": "Reset tenant password", "parameters": [ { "description": "Reset password", @@ -8582,6 +9700,40 @@ } } }, + "domain.AtlasGameEntity": { + "type": "object", + "properties": { + "demo_url": { + "description": "✅ new field", + "type": "string" + }, + "deviceType": { + "type": "string" + }, + "game_id": { + "type": "string" + }, + "hasFreeBets": { + "type": "boolean" + }, + "has_demo": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "providerId": { + "type": "string" + }, + "thumbnail_img_url": { + "description": "✅ new field", + "type": "string" + }, + "type": { + "type": "string" + } + } + }, "domain.AtlasGameInitRequest": { "type": "object", "properties": { @@ -8725,7 +9877,7 @@ "type": "string" }, "id": { - "type": "string" + "type": "integer" }, "isLive": { "type": "boolean" @@ -8757,6 +9909,9 @@ "source": { "$ref": "#/definitions/domain.EventSource" }, + "sourceEventID": { + "type": "string" + }, "sportID": { "type": "integer" }, @@ -9339,9 +10494,15 @@ "type": "number", "example": 0.1 }, + "is_active": { + "type": "boolean" + }, "name": { "type": "string", "example": "CompanyName" + }, + "slug": { + "type": "string" } } }, @@ -9583,6 +10744,172 @@ } } }, + "domain.EnetpulseSport": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "description": "DB primary key", + "type": "integer" + }, + "last_updated_at": { + "type": "string" + }, + "name": { + "description": "from API \"name\"", + "type": "string" + }, + "sport_id": { + "description": "from API \"id\"", + "type": "string" + }, + "status": { + "description": "active/inactive", + "type": "integer" + }, + "updated_at": { + "type": "string" + }, + "updates_count": { + "description": "from API \"n\"", + "type": "integer" + } + } + }, + "domain.EnetpulseTournament": { + "type": "object", + "properties": { + "createdAt": { + "type": "string" + }, + "id": { + "description": "internal DB PK", + "type": "integer" + }, + "lastUpdatedAt": { + "type": "string" + }, + "name": { + "type": "string" + }, + "status": { + "type": "integer" + }, + "tournamentID": { + "type": "string" + }, + "tournamentTemplateFK": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "updatesCount": { + "type": "integer" + } + } + }, + "domain.EnetpulseTournamentStage": { + "type": "object", + "properties": { + "country_fk": { + "description": "country FK from API", + "type": "string" + }, + "country_name": { + "description": "country name from API", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "end_date": { + "description": "end date/time", + "type": "string" + }, + "gender": { + "description": "male/female/mixed/unknown", + "type": "string" + }, + "id": { + "type": "integer" + }, + "last_updated_at": { + "description": "ut from API", + "type": "string" + }, + "name": { + "description": "API name", + "type": "string" + }, + "stage_id": { + "description": "API id", + "type": "string" + }, + "start_date": { + "description": "start date/time", + "type": "string" + }, + "status": { + "description": "active/inactive", + "type": "integer" + }, + "tournament_fk": { + "description": "Foreign key to tournament", + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "updates_count": { + "description": "n from API", + "type": "integer" + } + } + }, + "domain.EnetpulseTournamentTemplate": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "gender": { + "description": "male, female, mixed, unknown", + "type": "string" + }, + "id": { + "type": "integer" + }, + "last_updated_at": { + "type": "string" + }, + "name": { + "description": "from API \"name\"", + "type": "string" + }, + "sport_fk": { + "description": "related sport id", + "type": "string" + }, + "status": { + "description": "optional", + "type": "integer" + }, + "template_id": { + "description": "from API \"id\"", + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "updates_count": { + "description": "from API \"n\"", + "type": "integer" + } + } + }, "domain.ErrorResponse": { "type": "object", "properties": { @@ -9659,6 +10986,15 @@ "away_team_image": { "type": "string" }, + "default_is_active": { + "type": "boolean" + }, + "default_is_featured": { + "type": "boolean" + }, + "default_winning_upper_limit": { + "type": "integer" + }, "fetched_at": { "type": "string" }, @@ -9672,7 +11008,7 @@ "type": "string" }, "id": { - "type": "string" + "type": "integer" }, "is_active": { "type": "boolean" @@ -9710,6 +11046,9 @@ "source": { "$ref": "#/definitions/domain.EventSource" }, + "source_event_id": { + "type": "string" + }, "sport_id": { "type": "integer" }, @@ -10336,11 +11675,17 @@ "domain.OddMarketWithEventFilter": { "type": "object", "properties": { + "isLive": { + "$ref": "#/definitions/domain.ValidBool" + }, "limit": { "$ref": "#/definitions/domain.ValidInt32" }, "offset": { "$ref": "#/definitions/domain.ValidInt32" + }, + "status": { + "$ref": "#/definitions/domain.ValidString" } } }, @@ -10509,6 +11854,41 @@ } } }, + "domain.PreMatchOddsResponse": { + "type": "object", + "properties": { + "eventFK": { + "description": "Define fields according to the Enetpulse preodds response structure\nExample:", + "type": "integer" + }, + "odds": { + "type": "array", + "items": { + "$ref": "#/definitions/domain.PreMatchOutcome" + } + } + } + }, + "domain.PreMatchOutcome": { + "type": "object", + "properties": { + "oddsProviderFK": { + "type": "integer" + }, + "oddsValue": { + "type": "number" + }, + "outcomeFK": { + "type": "integer" + }, + "outcomeTypeFK": { + "type": "integer" + }, + "outcomeValue": { + "type": "string" + } + } + }, "domain.ProviderRequest": { "type": "object", "properties": { @@ -10595,55 +11975,14 @@ } } }, - "domain.ReferralSettings": { - "type": "object", - "properties": { - "betReferralBonusPercentage": { - "type": "number" - }, - "cashbackPercentage": { - "type": "number" - }, - "createdAt": { - "type": "string" - }, - "expiresAfterDays": { - "type": "integer" - }, - "id": { - "type": "integer" - }, - "maxReferrals": { - "type": "integer" - }, - "referralRewardAmount": { - "type": "number" - }, - "updatedAt": { - "type": "string" - }, - "updatedBy": { - "type": "string" - }, - "version": { - "type": "integer" - } - } - }, "domain.ReferralStats": { "type": "object", "properties": { - "completedReferrals": { - "type": "integer" - }, - "pendingRewards": { - "type": "number" - }, "totalReferrals": { "type": "integer" }, "totalRewardEarned": { - "type": "number" + "type": "integer" } } }, @@ -10705,14 +12044,16 @@ "admin", "branch_manager", "customer", - "cashier" + "cashier", + "transaction_approver" ], "x-enum-varnames": [ "RoleSuperAdmin", "RoleAdmin", "RoleBranchManager", "RoleCustomer", - "RoleCashier" + "RoleCashier", + "RoleTransactionApprover" ] }, "domain.RollbackRequest": { @@ -10947,6 +12288,10 @@ "type": "string", "example": "2025-04-08T12:00:00Z" }, + "fast_code": { + "type": "string", + "example": "12SD1" + }, "full_name": { "type": "string", "example": "John" @@ -11354,6 +12699,9 @@ "category": { "type": "string" }, + "demoUrl": { + "type": "string" + }, "deviceType": { "type": "string" }, @@ -11407,6 +12755,9 @@ "name": { "type": "string", "example": "CompanyName" + }, + "slug": { + "type": "string" } } }, @@ -11419,6 +12770,17 @@ } } }, + "domain.ValidBool": { + "type": "object", + "properties": { + "valid": { + "type": "boolean" + }, + "value": { + "type": "boolean" + } + } + }, "domain.ValidInt": { "type": "object", "properties": { @@ -11740,6 +13102,35 @@ } } }, + "handlers.CreateTransactionApproverReq": { + "type": "object", + "properties": { + "company_id": { + "type": "integer", + "example": 1 + }, + "email": { + "type": "string", + "example": "john.doe@example.com" + }, + "first_name": { + "type": "string", + "example": "John" + }, + "last_name": { + "type": "string", + "example": "Doe" + }, + "password": { + "type": "string", + "example": "password123" + }, + "phone_number": { + "type": "string", + "example": "1234567890" + } + } + }, "handlers.CreateTransferReq": { "type": "object", "properties": { @@ -11861,6 +13252,12 @@ "handlers.CustomersRes": { "type": "object", "properties": { + "company_id": { + "type": "integer" + }, + "company_name": { + "type": "string" + }, "created_at": { "type": "string" }, @@ -12042,7 +13439,7 @@ "type": "string", "example": "1234567890" }, - "referal_code": { + "referral_code": { "type": "string", "example": "ABC123" } @@ -12505,10 +13902,6 @@ "handlers.updateCustomerReq": { "type": "object", "properties": { - "company_id": { - "type": "integer", - "example": 1 - }, "first_name": { "type": "string", "example": "John" diff --git a/docs/swagger.yaml b/docs/swagger.yaml index b54bc7b..9a56b7a 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -92,6 +92,29 @@ definitions: player_id: type: string type: object + domain.AtlasGameEntity: + properties: + demo_url: + description: ✅ new field + type: string + deviceType: + type: string + game_id: + type: string + has_demo: + type: boolean + hasFreeBets: + type: boolean + name: + type: string + providerId: + type: string + thumbnail_img_url: + description: ✅ new field + type: string + type: + type: string + type: object domain.AtlasGameInitRequest: properties: currency: @@ -187,7 +210,7 @@ definitions: homeTeamImage: type: string id: - type: string + type: integer isLive: type: boolean isMonitored: @@ -208,6 +231,8 @@ definitions: $ref: '#/definitions/domain.ValidString' source: $ref: '#/definitions/domain.EventSource' + sourceEventID: + type: string sportID: type: integer startTime: @@ -613,9 +638,13 @@ definitions: deducted_percentage: example: 0.1 type: number + is_active: + type: boolean name: example: CompanyName type: string + slug: + type: string type: object domain.CreateSupportedOperationReq: properties: @@ -777,6 +806,123 @@ definitions: - customer_id - sender_account type: object + domain.EnetpulseSport: + properties: + created_at: + type: string + id: + description: DB primary key + type: integer + last_updated_at: + type: string + name: + description: from API "name" + type: string + sport_id: + description: from API "id" + type: string + status: + description: active/inactive + type: integer + updated_at: + type: string + updates_count: + description: from API "n" + type: integer + type: object + domain.EnetpulseTournament: + properties: + createdAt: + type: string + id: + description: internal DB PK + type: integer + lastUpdatedAt: + type: string + name: + type: string + status: + type: integer + tournamentID: + type: string + tournamentTemplateFK: + type: string + updatedAt: + type: string + updatesCount: + type: integer + type: object + domain.EnetpulseTournamentStage: + properties: + country_fk: + description: country FK from API + type: string + country_name: + description: country name from API + type: string + created_at: + type: string + end_date: + description: end date/time + type: string + gender: + description: male/female/mixed/unknown + type: string + id: + type: integer + last_updated_at: + description: ut from API + type: string + name: + description: API name + type: string + stage_id: + description: API id + type: string + start_date: + description: start date/time + type: string + status: + description: active/inactive + type: integer + tournament_fk: + description: Foreign key to tournament + type: string + updated_at: + type: string + updates_count: + description: n from API + type: integer + type: object + domain.EnetpulseTournamentTemplate: + properties: + created_at: + type: string + gender: + description: male, female, mixed, unknown + type: string + id: + type: integer + last_updated_at: + type: string + name: + description: from API "name" + type: string + sport_fk: + description: related sport id + type: string + status: + description: optional + type: integer + template_id: + description: from API "id" + type: string + updated_at: + type: string + updates_count: + description: from API "n" + type: integer + type: object domain.ErrorResponse: properties: error: @@ -838,6 +984,12 @@ definitions: type: integer away_team_image: type: string + default_is_active: + type: boolean + default_is_featured: + type: boolean + default_winning_upper_limit: + type: integer fetched_at: type: string home_team: @@ -847,7 +999,7 @@ definitions: home_team_image: type: string id: - type: string + type: integer is_active: type: boolean is_featured: @@ -872,6 +1024,8 @@ definitions: type: string source: $ref: '#/definitions/domain.EventSource' + source_event_id: + type: string sport_id: type: integer start_time: @@ -1289,10 +1443,14 @@ definitions: type: object domain.OddMarketWithEventFilter: properties: + isLive: + $ref: '#/definitions/domain.ValidBool' limit: $ref: '#/definitions/domain.ValidInt32' offset: $ref: '#/definitions/domain.ValidInt32' + status: + $ref: '#/definitions/domain.ValidString' type: object domain.OutcomeStatus: enum: @@ -1411,6 +1569,31 @@ definitions: thumbnail: type: string type: object + domain.PreMatchOddsResponse: + properties: + eventFK: + description: |- + Define fields according to the Enetpulse preodds response structure + Example: + type: integer + odds: + items: + $ref: '#/definitions/domain.PreMatchOutcome' + type: array + type: object + domain.PreMatchOutcome: + properties: + oddsProviderFK: + type: integer + oddsValue: + type: number + outcomeFK: + type: integer + outcomeTypeFK: + type: integer + outcomeValue: + type: string + type: object domain.ProviderRequest: properties: brandId: @@ -1468,39 +1651,12 @@ definitions: type: object type: array type: object - domain.ReferralSettings: - properties: - betReferralBonusPercentage: - type: number - cashbackPercentage: - type: number - createdAt: - type: string - expiresAfterDays: - type: integer - id: - type: integer - maxReferrals: - type: integer - referralRewardAmount: - type: number - updatedAt: - type: string - updatedBy: - type: string - version: - type: integer - type: object domain.ReferralStats: properties: - completedReferrals: - type: integer - pendingRewards: - type: number totalReferrals: type: integer totalRewardEarned: - type: number + type: integer type: object domain.ReportedIssue: properties: @@ -1543,6 +1699,7 @@ definitions: - branch_manager - customer - cashier + - transaction_approver type: string x-enum-varnames: - RoleSuperAdmin @@ -1550,6 +1707,7 @@ definitions: - RoleBranchManager - RoleCustomer - RoleCashier + - RoleTransactionApprover domain.RollbackRequest: properties: bet_transaction_id: @@ -1706,6 +1864,9 @@ definitions: created_at: example: "2025-04-08T12:00:00Z" type: string + fast_code: + example: 12SD1 + type: string full_name: example: John type: string @@ -1992,6 +2153,8 @@ definitions: type: array category: type: string + demoUrl: + type: string deviceType: type: string gameId: @@ -2029,6 +2192,8 @@ definitions: name: example: CompanyName type: string + slug: + type: string type: object domain.UpdateTransactionVerifiedReq: properties: @@ -2036,6 +2201,13 @@ definitions: example: true type: boolean type: object + domain.ValidBool: + properties: + valid: + type: boolean + value: + type: boolean + type: object domain.ValidInt: properties: valid: @@ -2253,6 +2425,27 @@ definitions: example: "1234567890" type: string type: object + handlers.CreateTransactionApproverReq: + properties: + company_id: + example: 1 + type: integer + email: + example: john.doe@example.com + type: string + first_name: + example: John + type: string + last_name: + example: Doe + type: string + password: + example: password123 + type: string + phone_number: + example: "1234567890" + type: string + type: object handlers.CreateTransferReq: properties: amount: @@ -2337,6 +2530,10 @@ definitions: type: object handlers.CustomersRes: properties: + company_id: + type: integer + company_name: + type: string created_at: type: string email: @@ -2459,7 +2656,7 @@ definitions: phone_number: example: "1234567890" type: string - referal_code: + referral_code: example: ABC123 type: string type: object @@ -2774,9 +2971,6 @@ definitions: type: object handlers.updateCustomerReq: properties: - company_id: - example: 1 - type: integer first_name: example: John type: string @@ -2986,35 +3180,6 @@ paths: summary: Retrieve all upcoming events with settings tags: - prematch - /api/v1/{tenant_slug}/events/{id}/settings: - put: - consumes: - - application/json - description: Update the event settings - parameters: - - description: Event ID - in: path - name: id - required: true - type: integer - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/response.APIResponse' - "400": - description: Bad Request - schema: - $ref: '#/definitions/response.APIResponse' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/response.APIResponse' - summary: update the event settings - tags: - - event /api/v1/{tenant_slug}/leagues: get: consumes: @@ -3684,7 +3849,7 @@ paths: post: consumes: - application/json - description: Reset password + description: Reset tenant password parameters: - description: Reset password in: body @@ -3707,7 +3872,7 @@ paths: description: Internal Server Error schema: $ref: '#/definitions/response.APIResponse' - summary: Reset password + summary: Reset tenant password tags: - user /api/v1/{tenant_slug}/user/search: @@ -3899,14 +4064,14 @@ paths: post: consumes: - application/json - description: Create Admin + description: Create transaction approver parameters: - - description: Create admin + - description: Create transaction approver in: body name: manger required: true schema: - $ref: '#/definitions/handlers.CreateAdminReq' + $ref: '#/definitions/handlers.CreateTransactionApproverReq' produces: - application/json responses: @@ -3926,7 +4091,7 @@ paths: description: Internal Server Error schema: $ref: '#/definitions/response.APIResponse' - summary: Create Admin + summary: Create transaction approver tags: - admin /api/v1/admin-company: @@ -4339,6 +4504,30 @@ paths: summary: Create free spins for a player tags: - Virtual Games - Atlas + /api/v1/atlas/games: + get: + description: Retrieves available Atlas virtual games from the provider + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/domain.Response' + - properties: + data: + items: + $ref: '#/definitions/domain.AtlasGameEntity' + type: array + type: object + "502": + description: Bad Gateway + schema: + $ref: '#/definitions/domain.ErrorResponse' + summary: List Atlas virtual games + tags: + - Virtual Games - Atlas /api/v1/atlas/init-game: post: consumes: @@ -4873,6 +5062,35 @@ paths: summary: Delete the branch operation tags: - branch + /api/v1/branch/{id}/return: + post: + consumes: + - application/json + description: Unassign the branch wallet to company + parameters: + - description: Branch ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/domain.BranchDetailRes' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Unassign the branch wallet to company + tags: + - branch /api/v1/branchCashier: get: consumes: @@ -5616,6 +5834,39 @@ paths: summary: Update Customers tags: - customer + /api/v1/customer/{id}/bets: + get: + consumes: + - application/json + description: Get customer bets + parameters: + - description: User ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handlers.CustomersRes' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Get customer bets + tags: + - customer /api/v1/customerWallet: get: consumes: @@ -5722,6 +5973,110 @@ paths: summary: Verify a direct deposit tags: - Direct Deposits + /api/v1/enetpulse/sports: + get: + consumes: + - application/json + description: Fetches all sports stored in the database + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/domain.Response' + - properties: + data: + items: + $ref: '#/definitions/domain.EnetpulseSport' + type: array + type: object + "502": + description: Bad Gateway + schema: + $ref: '#/definitions/domain.ErrorResponse' + summary: Get all sports + tags: + - EnetPulse - Sports + /api/v1/enetpulse/tournament-stages: + get: + consumes: + - application/json + description: Fetches all tournament stages stored in the database + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/domain.Response' + - properties: + data: + items: + $ref: '#/definitions/domain.EnetpulseTournamentStage' + type: array + type: object + "502": + description: Bad Gateway + schema: + $ref: '#/definitions/domain.ErrorResponse' + summary: Get all tournament stages + tags: + - EnetPulse - Tournament Stages + /api/v1/enetpulse/tournament-templates: + get: + consumes: + - application/json + description: Fetches all tournament templates stored in the database + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/domain.Response' + - properties: + data: + items: + $ref: '#/definitions/domain.EnetpulseTournamentTemplate' + type: array + type: object + "502": + description: Bad Gateway + schema: + $ref: '#/definitions/domain.ErrorResponse' + summary: Get all tournament templates + tags: + - EnetPulse - Tournament Templates + /api/v1/enetpulse/tournaments: + get: + consumes: + - application/json + description: Fetches all tournaments stored in the database + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/domain.Response' + - properties: + data: + items: + $ref: '#/definitions/domain.EnetpulseTournament' + type: array + type: object + "502": + description: Bad Gateway + schema: + $ref: '#/definitions/domain.ErrorResponse' + summary: Get all tournaments + tags: + - EnetPulse - Tournaments /api/v1/events: get: consumes: @@ -5829,6 +6184,93 @@ paths: summary: Retrieve an upcoming by ID tags: - prematch + /api/v1/events/{id}/bets: + get: + consumes: + - application/json + description: Retrieve bet outcomes by event id + parameters: + - description: ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/domain.BaseEvent' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Retrieve bet outcomes by event id + tags: + - prematch + /api/v1/events/{id}/is_monitored: + patch: + consumes: + - application/json + description: Update the event is_monitored + parameters: + - description: Event ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.APIResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: update the event is_monitored + tags: + - event + /api/v1/events/{id}/settings: + put: + consumes: + - application/json + description: Update the event settings + parameters: + - description: Event ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.APIResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: update the event settings + tags: + - event /api/v1/issues: get: description: Admin endpoint to list all reported issues with pagination @@ -6231,6 +6673,71 @@ paths: summary: Retrieve all odds tags: - prematch + /api/v1/odds/pre-match: + get: + consumes: + - application/json + description: Fetches pre-match odds from EnetPulse for a given event + parameters: + - description: Event ID + in: query + name: objectFK + required: true + type: integer + - collectionFormat: csv + description: Odds provider IDs (comma separated) + in: query + items: + type: integer + name: oddsProviderFK + type: array + - description: Outcome type ID + in: query + name: outcomeTypeFK + type: integer + - description: Outcome scope ID + in: query + name: outcomeScopeFK + type: integer + - description: Outcome subtype ID + in: query + name: outcomeSubtypeFK + type: integer + - description: Limit results + in: query + name: limit + type: integer + - description: Offset results + in: query + name: offset + type: integer + - description: Language type ID + in: query + name: languageTypeFK + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/domain.Response' + - properties: + data: + $ref: '#/definitions/domain.PreMatchOddsResponse' + type: object + "400": + description: Bad Request + schema: + $ref: '#/definitions/domain.ErrorResponse' + "502": + description: Bad Gateway + schema: + $ref: '#/definitions/domain.ErrorResponse' + summary: Get pre-match odds for an event + tags: + - EnetPulse - PreMatch /api/v1/odds/upcoming/{upcoming_id}: get: consumes: @@ -6385,95 +6892,6 @@ paths: summary: List all virtual games tags: - VirtualGames - Orchestration - /api/v1/referral/settings: - get: - consumes: - - application/json - description: Retrieves current referral settings (admin only) - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/domain.ReferralSettings' - "401": - description: Unauthorized - schema: - $ref: '#/definitions/response.APIResponse' - "403": - description: Forbidden - schema: - $ref: '#/definitions/response.APIResponse' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/response.APIResponse' - security: - - Bearer: [] - summary: Get referral settings - tags: - - referral - put: - consumes: - - application/json - description: Updates referral settings (admin only) - parameters: - - description: Referral settings - in: body - name: settings - required: true - schema: - $ref: '#/definitions/domain.ReferralSettings' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/response.APIResponse' - "401": - description: Unauthorized - schema: - $ref: '#/definitions/response.APIResponse' - "403": - description: Forbidden - schema: - $ref: '#/definitions/response.APIResponse' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/response.APIResponse' - security: - - Bearer: [] - summary: Update referral settings - tags: - - referral - /api/v1/referral/stats: - get: - consumes: - - application/json - description: Retrieves referral statistics for the authenticated user - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/domain.ReferralStats' - "401": - description: Unauthorized - schema: - $ref: '#/definitions/response.APIResponse' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/response.APIResponse' - security: - - Bearer: [] - summary: Get referral statistics - tags: - - referral /api/v1/report-files/download/{filename}: get: description: Downloads a generated report CSV file from the server @@ -6600,7 +7018,7 @@ paths: summary: Get dashboard report tags: - Reports - /api/v1/result/{id}: + /api/v1/result/b365/{id}: get: consumes: - application/json @@ -7181,6 +7599,63 @@ paths: summary: Gets shop bet by transaction id tags: - transaction + /api/v1/sport/bet/{id}: + delete: + consumes: + - application/json + description: Deletes bet by id + parameters: + - description: Bet ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.APIResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Deletes bet by id + tags: + - bet + get: + consumes: + - application/json + description: Gets a single bet by id + parameters: + - description: Bet ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/domain.BetRes' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Gets bet by id + tags: + - bet /api/v1/super-login: post: consumes: @@ -7269,6 +7744,108 @@ paths: summary: Create a supported operation tags: - branch + /api/v1/t-approver: + get: + consumes: + - application/json + description: Get all Admins + parameters: + - description: Page number + in: query + name: page + type: integer + - description: Page size + in: query + name: page_size + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handlers.AdminRes' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Get all Admins + tags: + - admin + /api/v1/t-approver/{id}: + get: + consumes: + - application/json + description: Get a single admin by id + parameters: + - description: User ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handlers.AdminRes' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Get admin by id + tags: + - admin + put: + consumes: + - application/json + description: Update Admin + parameters: + - description: Update Admin + in: body + name: admin + required: true + schema: + $ref: '#/definitions/handlers.updateAdminReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.APIResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Update Admin + tags: + - admin /api/v1/telebirr/callback: post: consumes: @@ -7329,6 +7906,254 @@ paths: summary: Create Telebirr Payment Session tags: - Telebirr + /api/v1/tenant: + get: + consumes: + - application/json + description: Check if phone number or email exist + parameters: + - description: Check phone number or email exist + in: body + name: checkPhoneEmailExist + required: true + schema: + $ref: '#/definitions/handlers.CheckPhoneEmailExistReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handlers.CheckPhoneEmailExistRes' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Check if phone number or email exist + tags: + - user + /api/v1/tenant/{tenant_slug}/customer: + get: + consumes: + - application/json + description: Get all Customers + parameters: + - description: Page number + in: query + name: page + type: integer + - description: Page size + in: query + name: page_size + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handlers.CustomersRes' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Get all Customers + tags: + - customer + /api/v1/tenant/{tenant_slug}/customer/{id}: + get: + consumes: + - application/json + description: Get a single customer by id + parameters: + - description: User ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handlers.CustomersRes' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Get customer by id + tags: + - customer + put: + consumes: + - application/json + description: Update Customers + parameters: + - description: Update Customers + in: body + name: Customers + required: true + schema: + $ref: '#/definitions/handlers.updateCustomerReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.APIResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Update Customers + tags: + - customer + /api/v1/tenant/{tenant_slug}/customer/{id}/bets: + get: + consumes: + - application/json + description: Get tenant customer bets + parameters: + - description: User ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handlers.CustomersRes' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Get tenant customer bets + tags: + - customer + /api/v1/tenant/{tenant_slug}/events/{id}/bets: + get: + consumes: + - application/json + description: Retrieve bet outcomes by event id + parameters: + - description: ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/domain.BaseEvent' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Retrieve bet outcomes by event id + tags: + - prematch + /api/v1/tenant/{tenant_slug}/events/{id}/settings: + put: + consumes: + - application/json + description: Update the event settings + parameters: + - description: Event ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.APIResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: update the event settings + tags: + - event + /api/v1/tenant/{tenant_slug}/referral/stats: + get: + consumes: + - application/json + description: Retrieves referral statistics for the authenticated user + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/domain.ReferralStats' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + security: + - Bearer: [] + summary: Get referral statistics + tags: + - referral /api/v1/transfer/refill/:id: post: consumes: @@ -7448,6 +8273,96 @@ paths: summary: Delete user by ID tags: - user + /api/v1/user/resetPassword: + post: + consumes: + - application/json + description: Reset password + parameters: + - description: Reset password + in: body + name: resetPassword + required: true + schema: + $ref: '#/definitions/handlers.ResetPasswordReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.APIResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Reset password + tags: + - user + /api/v1/user/search: + post: + consumes: + - application/json + description: Search for user using name or phone + parameters: + - description: Search for using his name or phone + in: body + name: searchUserByNameOrPhone + required: true + schema: + $ref: '#/definitions/handlers.SearchUserByNameOrPhoneReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handlers.UserProfileRes' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Search for user using name or phone + tags: + - user + /api/v1/user/sendResetCode: + post: + consumes: + - application/json + description: Send reset code + parameters: + - description: Send reset code + in: body + name: resetCode + required: true + schema: + $ref: '#/definitions/handlers.ResetCodeReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.APIResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.APIResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.APIResponse' + summary: Send reset code + tags: + - user /api/v1/user/single/{id}: get: consumes: diff --git a/gen/db/company.sql.go b/gen/db/company.sql.go index ba728e7..32d9ee2 100644 --- a/gen/db/company.sql.go +++ b/gen/db/company.sql.go @@ -17,9 +17,10 @@ INSERT INTO companies ( slug, admin_id, wallet_id, - deducted_percentage + deducted_percentage, + is_active ) -VALUES ($1, $2, $3, $4, $5) +VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at ` @@ -29,6 +30,7 @@ type CreateCompanyParams struct { AdminID int64 `json:"admin_id"` WalletID int64 `json:"wallet_id"` DeductedPercentage float32 `json:"deducted_percentage"` + IsActive bool `json:"is_active"` } func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (Company, error) { @@ -38,6 +40,7 @@ func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (C arg.AdminID, arg.WalletID, arg.DeductedPercentage, + arg.IsActive, ) var i Company err := row.Scan( @@ -217,7 +220,7 @@ func (q *Queries) SearchCompanyByName(ctx context.Context, dollar_1 pgtype.Text) return items, nil } -const UpdateCompany = `-- name: UpdateCompany :one +const UpdateCompany = `-- name: UpdateCompany :exec UPDATE companies SET name = COALESCE($2, name), admin_id = COALESCE($3, admin_id), @@ -226,9 +229,9 @@ SET name = COALESCE($2, name), $5, deducted_percentage ), + slug = COALESCE($6, slug), updated_at = CURRENT_TIMESTAMP WHERE id = $1 -RETURNING id, name, slug, admin_id, wallet_id, deducted_percentage, is_active, created_at, updated_at ` type UpdateCompanyParams struct { @@ -237,27 +240,17 @@ type UpdateCompanyParams struct { AdminID pgtype.Int8 `json:"admin_id"` IsActive pgtype.Bool `json:"is_active"` DeductedPercentage pgtype.Float4 `json:"deducted_percentage"` + Slug pgtype.Text `json:"slug"` } -func (q *Queries) UpdateCompany(ctx context.Context, arg UpdateCompanyParams) (Company, error) { - row := q.db.QueryRow(ctx, UpdateCompany, +func (q *Queries) UpdateCompany(ctx context.Context, arg UpdateCompanyParams) error { + _, err := q.db.Exec(ctx, UpdateCompany, arg.ID, arg.Name, arg.AdminID, arg.IsActive, arg.DeductedPercentage, + arg.Slug, ) - var i Company - err := row.Scan( - &i.ID, - &i.Name, - &i.Slug, - &i.AdminID, - &i.WalletID, - &i.DeductedPercentage, - &i.IsActive, - &i.CreatedAt, - &i.UpdatedAt, - ) - return i, err + return err } diff --git a/gen/db/leagues.sql.go b/gen/db/leagues.sql.go index 912e257..1413699 100644 --- a/gen/db/leagues.sql.go +++ b/gen/db/leagues.sql.go @@ -48,14 +48,19 @@ WHERE ( name ILIKE '%' || $3 || '%' OR $3 IS NULL ) + AND ( + default_is_active = $4 + OR $4 IS NULL + ) ORDER BY name ASC -LIMIT $5 OFFSET $4 +LIMIT $6 OFFSET $5 ` type GetAllLeaguesParams struct { CountryCode pgtype.Text `json:"country_code"` SportID pgtype.Int4 `json:"sport_id"` Query pgtype.Text `json:"query"` + IsActive pgtype.Bool `json:"is_active"` Offset pgtype.Int4 `json:"offset"` Limit pgtype.Int4 `json:"limit"` } @@ -65,6 +70,7 @@ func (q *Queries) GetAllLeagues(ctx context.Context, arg GetAllLeaguesParams) ([ arg.CountryCode, arg.SportID, arg.Query, + arg.IsActive, arg.Offset, arg.Limit, ) @@ -199,6 +205,46 @@ func (q *Queries) GetAllLeaguesWithSettings(ctx context.Context, arg GetAllLeagu return items, nil } +const GetTotalLeagues = `-- name: GetTotalLeagues :one +SELECT COUNT(*) +FROM leagues +WHERE ( + country_code = $1 + OR $1 IS NULL + ) + AND ( + sport_id = $2 + OR $2 IS NULL + ) + AND ( + name ILIKE '%' || $3 || '%' + OR $3 IS NULL + ) + AND ( + default_is_active = $4 + OR $4 IS NULL + ) +` + +type GetTotalLeaguesParams struct { + CountryCode pgtype.Text `json:"country_code"` + SportID pgtype.Int4 `json:"sport_id"` + Query pgtype.Text `json:"query"` + IsActive pgtype.Bool `json:"is_active"` +} + +func (q *Queries) GetTotalLeagues(ctx context.Context, arg GetTotalLeaguesParams) (int64, error) { + row := q.db.QueryRow(ctx, GetTotalLeagues, + arg.CountryCode, + arg.SportID, + arg.Query, + arg.IsActive, + ) + var count int64 + err := row.Scan(&count) + return count, err +} + const GetTotalLeaguesWithSettings = `-- name: GetTotalLeaguesWithSettings :one SELECT COUNT(*) FROM leagues l diff --git a/gen/db/models.go b/gen/db/models.go index 339efb8..d91297f 100644 --- a/gen/db/models.go +++ b/gen/db/models.go @@ -687,6 +687,7 @@ type ShopBetDetail struct { TransactionVerified bool `json:"transaction_verified"` Status int32 `json:"status"` TotalOdds float32 `json:"total_odds"` + FastCode string `json:"fast_code"` Outcomes []BetOutcome `json:"outcomes"` } diff --git a/gen/db/shop_transactions.sql.go b/gen/db/shop_transactions.sql.go index bcd884e..5c4b52e 100644 --- a/gen/db/shop_transactions.sql.go +++ b/gen/db/shop_transactions.sql.go @@ -173,7 +173,7 @@ func (q *Queries) CreateShopTransaction(ctx context.Context, arg CreateShopTrans } const GetAllShopBets = `-- name: GetAllShopBets :many -SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes +SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, fast_code, outcomes FROM shop_bet_detail WHERE ( full_name ILIKE '%' || $1 || '%' @@ -239,6 +239,7 @@ func (q *Queries) GetAllShopBets(ctx context.Context, arg GetAllShopBetsParams) &i.TransactionVerified, &i.Status, &i.TotalOdds, + &i.FastCode, &i.Outcomes, ); err != nil { return nil, err @@ -419,7 +420,7 @@ func (q *Queries) GetAllShopTransactions(ctx context.Context, arg GetAllShopTran } const GetShopBetByBetID = `-- name: GetShopBetByBetID :one -SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes +SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, fast_code, outcomes FROM shop_bet_detail WHERE bet_id = $1 ` @@ -445,13 +446,14 @@ func (q *Queries) GetShopBetByBetID(ctx context.Context, betID int64) (ShopBetDe &i.TransactionVerified, &i.Status, &i.TotalOdds, + &i.FastCode, &i.Outcomes, ) return i, err } const GetShopBetByCashoutID = `-- name: GetShopBetByCashoutID :one -SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes +SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, fast_code, outcomes FROM shop_bet_detail WHERE cashout_id = $1 ` @@ -477,13 +479,14 @@ func (q *Queries) GetShopBetByCashoutID(ctx context.Context, cashoutID string) ( &i.TransactionVerified, &i.Status, &i.TotalOdds, + &i.FastCode, &i.Outcomes, ) return i, err } const GetShopBetByID = `-- name: GetShopBetByID :one -SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes +SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, fast_code, outcomes FROM shop_bet_detail WHERE id = $1 ` @@ -509,13 +512,14 @@ func (q *Queries) GetShopBetByID(ctx context.Context, id int64) (ShopBetDetail, &i.TransactionVerified, &i.Status, &i.TotalOdds, + &i.FastCode, &i.Outcomes, ) return i, err } const GetShopBetByShopTransactionID = `-- name: GetShopBetByShopTransactionID :one -SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, outcomes +SELECT id, shop_transaction_id, cashout_id, cashed_out_by, bet_id, number_of_outcomes, cashed_out, created_at, updated_at, customer_full_name, customer_phone_number, branch_id, company_id, amount, transaction_verified, status, total_odds, fast_code, outcomes FROM shop_bet_detail WHERE shop_transaction_id = $1 ` @@ -541,6 +545,7 @@ func (q *Queries) GetShopBetByShopTransactionID(ctx context.Context, shopTransac &i.TransactionVerified, &i.Status, &i.TotalOdds, + &i.FastCode, &i.Outcomes, ) return i, err diff --git a/internal/domain/company.go b/internal/domain/company.go index 0d7eccd..f4ee64a 100644 --- a/internal/domain/company.go +++ b/internal/domain/company.go @@ -45,6 +45,8 @@ type CreateCompany struct { AdminID int64 WalletID int64 DeductedPercentage float32 + Slug string + IsActive bool } type UpdateCompany struct { @@ -53,18 +55,22 @@ type UpdateCompany struct { AdminID ValidInt64 IsActive ValidBool DeductedPercentage ValidFloat32 + Slug ValidString } type CreateCompanyReq struct { Name string `json:"name" example:"CompanyName"` AdminID int64 `json:"admin_id" example:"1"` DeductedPercentage float32 `json:"deducted_percentage" example:"0.1" validate:"lt=1"` + Slug string `json:"slug"` + IsActive bool `json:"is_active"` } type UpdateCompanyReq struct { Name *string `json:"name,omitempty" example:"CompanyName"` AdminID *int64 `json:"admin_id,omitempty" example:"1"` IsActive *bool `json:"is_active,omitempty" example:"true"` DeductedPercentage *float32 `json:"deducted_percentage,omitempty" example:"0.1" validate:"lt=1"` + Slug *string `json:"slug"` } type CompanyRes struct { @@ -113,13 +119,14 @@ func ConvertGetCompany(company GetCompany) GetCompanyRes { } } -func ConvertCreateCompany(company CreateCompany, uniqueSlug string) dbgen.CreateCompanyParams { +func ConvertCreateCompany(company CreateCompany) dbgen.CreateCompanyParams { return dbgen.CreateCompanyParams{ Name: company.Name, - Slug: uniqueSlug, + Slug: company.Slug, AdminID: company.AdminID, WalletID: company.WalletID, DeductedPercentage: company.DeductedPercentage, + IsActive: company.IsActive, } } @@ -154,31 +161,22 @@ func ConvertDBCompanyDetails(dbCompany dbgen.CompaniesDetail) GetCompany { func ConvertUpdateCompany(updateCompany UpdateCompany) dbgen.UpdateCompanyParams { newUpdateCompany := dbgen.UpdateCompanyParams{ - ID: updateCompany.ID, - Name: pgtype.Text{ - String: updateCompany.Name.Value, - Valid: updateCompany.Name.Valid, - }, - AdminID: pgtype.Int8{ - Int64: updateCompany.AdminID.Value, - Valid: updateCompany.AdminID.Valid, - }, - IsActive: pgtype.Bool{ - Bool: updateCompany.IsActive.Value, - Valid: updateCompany.IsActive.Valid, - }, - DeductedPercentage: pgtype.Float4{ - Float32: updateCompany.DeductedPercentage.Value, - Valid: updateCompany.DeductedPercentage.Valid, - }, + ID: updateCompany.ID, + Name: updateCompany.Name.ToPG(), + AdminID: updateCompany.AdminID.ToPG(), + IsActive: updateCompany.IsActive.ToPG(), + DeductedPercentage: updateCompany.DeductedPercentage.ToPG(), + Slug: updateCompany.Slug.ToPG(), } return newUpdateCompany } -func ConvertUpdateCompanyReq(req UpdateCompanyReq) UpdateCompany { +func ConvertUpdateCompanyReq(req UpdateCompanyReq, companyID int64) UpdateCompany { var updateCompany UpdateCompany + updateCompany.ID = companyID + if req.Name != nil { updateCompany.Name = ValidString{ Value: *req.Name, @@ -206,6 +204,12 @@ func ConvertUpdateCompanyReq(req UpdateCompanyReq) UpdateCompany { Valid: true, } } + if req.Slug != nil { + updateCompany.Slug = ValidString{ + Value: *req.Slug, + Valid: true, + } + } return updateCompany } diff --git a/internal/domain/shop_bet.go b/internal/domain/shop_bet.go index 72f280b..b46b4b6 100644 --- a/internal/domain/shop_bet.go +++ b/internal/domain/shop_bet.go @@ -34,6 +34,7 @@ type ShopBetDetail struct { CompanyID int64 FullName string PhoneNumber string + FastCode string CashoutID string CashedOut bool BetID int64 @@ -80,6 +81,7 @@ type ShopBetRes struct { CompanyID int64 `json:"company_id" example:"2"` FullName string `json:"full_name" example:"John"` PhoneNumber string `json:"phone_number" example:"1234567890"` + FastCode string `json:"fast_code" example:"12SD1"` CashoutID string `json:"cashout_id" example:"21234"` CashedOut bool `json:"cashed_out" example:"false"` BetID int64 `json:"bet_id" example:"1"` @@ -111,6 +113,7 @@ func ConvertShopBetDetail(shopBet ShopBetDetail) ShopBetRes { CompanyID: shopBet.CompanyID, FullName: shopBet.FullName, PhoneNumber: shopBet.PhoneNumber, + FastCode: shopBet.FastCode, CashoutID: shopBet.CashoutID, CashedOut: shopBet.CashedOut, BetID: shopBet.BetID, diff --git a/internal/domain/wallet.go b/internal/domain/wallet.go index 947f3c8..17d69d9 100644 --- a/internal/domain/wallet.go +++ b/internal/domain/wallet.go @@ -1,6 +1,13 @@ package domain -import "time" +import ( + "errors" + "time" +) + +var ( + ErrWalletIDDuplicate = errors.New("there already exists user id with wallet_type") +) type Wallet struct { ID int64 diff --git a/internal/repository/bet.go b/internal/repository/bet.go index 9a6ad8f..8de6a2a 100644 --- a/internal/repository/bet.go +++ b/internal/repository/bet.go @@ -103,8 +103,11 @@ func (s *Store) GetAllBets(ctx context.Context, filter domain.BetFilter) ([]doma Query: filter.Query.ToPG(), CreatedBefore: filter.CreatedBefore.ToPG(), CreatedAfter: filter.CreatedAfter.ToPG(), - Offset: filter.Offset.ToPG(), - Limit: filter.Limit.ToPG(), + Offset: pgtype.Int4{ + Int32: int32(filter.Offset.Value * filter.Limit.Value), + Valid: filter.Offset.Valid, + }, + Limit: filter.Limit.ToPG(), }) if err != nil { domain.MongoDBLogger.Error("failed to get all bets", diff --git a/internal/repository/common.go b/internal/repository/common.go new file mode 100644 index 0000000..5cf051e --- /dev/null +++ b/internal/repository/common.go @@ -0,0 +1,12 @@ +package repository + +import ( + "errors" + + "github.com/jackc/pgx/v5/pgconn" +) + +func IsUniqueViolation(err error) bool { + var pgErr *pgconn.PgError + return errors.As(err, &pgErr) && pgErr.Code == "23505" +} \ No newline at end of file diff --git a/internal/repository/company.go b/internal/repository/company.go index 1e290c9..a72310b 100644 --- a/internal/repository/company.go +++ b/internal/repository/company.go @@ -2,36 +2,34 @@ package repository import ( "context" - "errors" "fmt" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" - "github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers" - "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgtype" ) func (s *Store) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) { - baseSlug := helpers.GenerateSlug(company.Name) - uniqueSlug := baseSlug - i := 1 + // baseSlug := helpers.GenerateSlug(company.Name) + // uniqueSlug := baseSlug + // i := 1 - for { - _, err := s.queries.GetCompanyUsingSlug(ctx, uniqueSlug) - if err != nil { - if errors.Is(err, pgx.ErrNoRows) { - // slug is unique - break - } else { - // real DB error - return domain.Company{}, err - } - } - uniqueSlug = fmt.Sprintf("%s-%d", baseSlug, i) - i++ - } + // for { + // _, err := s.queries.GetCompanyUsingSlug(ctx, uniqueSlug) + // if err != nil { + // if errors.Is(err, pgx.ErrNoRows) { + // // slug is unique + // break + // } else { + // // real DB error + // return domain.Company{}, err + // } + // } + // uniqueSlug = fmt.Sprintf("%s-%d", baseSlug, i) + // i++ + // } + fmt.Printf("\ncompany %v\n\n", company) + dbCompany, err := s.queries.CreateCompany(ctx, domain.ConvertCreateCompany(company)) - dbCompany, err := s.queries.CreateCompany(ctx, domain.ConvertCreateCompany(company, uniqueSlug)) if err != nil { return domain.Company{}, err } @@ -87,14 +85,15 @@ func (s *Store) GetCompanyBySlug(ctx context.Context, slug string) (domain.Compa return domain.ConvertDBCompany(dbCompany), nil } -func (s *Store) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error) { - dbCompany, err := s.queries.UpdateCompany(ctx, domain.ConvertUpdateCompany(company)) +func (s *Store) UpdateCompany(ctx context.Context, company domain.UpdateCompany) error { + fmt.Printf("company %v\n", company) + err := s.queries.UpdateCompany(ctx, domain.ConvertUpdateCompany(company)) if err != nil { - return domain.Company{}, err + return err } - return domain.ConvertDBCompany(dbCompany), nil + return nil } func (s *Store) DeleteCompany(ctx context.Context, id int64) error { diff --git a/internal/repository/event.go b/internal/repository/event.go index 236de50..d5d217f 100644 --- a/internal/repository/event.go +++ b/internal/repository/event.go @@ -22,11 +22,15 @@ func (s *Store) GetLiveEventIDs(ctx context.Context) ([]int64, error) { func (s *Store) GetAllEvents(ctx context.Context, filter domain.EventFilter) ([]domain.BaseEvent, int64, error) { events, err := s.queries.GetAllEvents(ctx, dbgen.GetAllEventsParams{ - LeagueID: filter.LeagueID.ToPG(), - SportID: filter.SportID.ToPG(), - Query: filter.Query.ToPG(), - Limit: filter.Limit.ToPG(), - Offset: filter.Offset.ToPG(), + LeagueID: filter.LeagueID.ToPG(), + SportID: filter.SportID.ToPG(), + Query: filter.Query.ToPG(), + Limit: filter.Limit.ToPG(), + Offset: pgtype.Int4{ + Int32: int32(filter.Offset.Value * filter.Limit.Value), + Valid: filter.Offset.Valid, + }, + FirstStartTime: filter.FirstStartTime.ToPG(), LastStartTime: filter.LastStartTime.ToPG(), CountryCode: filter.CountryCode.ToPG(), diff --git a/internal/repository/league.go b/internal/repository/league.go index ab01c14..e2e614e 100644 --- a/internal/repository/league.go +++ b/internal/repository/league.go @@ -16,7 +16,7 @@ func (s *Store) SaveLeagueSettings(ctx context.Context, leagueSettings domain.Cr return s.queries.SaveLeagueSettings(ctx, domain.ConvertCreateLeagueSettings(leagueSettings)) } -func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error) { +func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague,int64, error) { l, err := s.queries.GetAllLeagues(ctx, dbgen.GetAllLeaguesParams{ Query: filter.Query.ToPG(), CountryCode: filter.CountryCode.ToPG(), @@ -31,10 +31,17 @@ func (s *Store) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ( }, }) if err != nil { - return nil, err + return nil, 0, err } - return domain.ConvertDBBaseLeagues(l), nil + total, err := s.queries.GetTotalLeagues(ctx, dbgen.GetTotalLeaguesParams{ + Query: filter.Query.ToPG(), + CountryCode: filter.CountryCode.ToPG(), + SportID: filter.SportID.ToPG(), + IsActive: filter.IsActive.ToPG(), + }) + + return domain.ConvertDBBaseLeagues(l), total, nil } func (s *Store) GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, int64, error) { diff --git a/internal/repository/shop_bet.go b/internal/repository/shop_bet.go index 66e3e63..3a5bd5a 100644 --- a/internal/repository/shop_bet.go +++ b/internal/repository/shop_bet.go @@ -35,6 +35,7 @@ func convertDBShopBetDetail(bet dbgen.ShopBetDetail) domain.ShopBetDetail { CompanyID: bet.CompanyID, FullName: bet.CustomerFullName, PhoneNumber: bet.CustomerPhoneNumber, + FastCode: bet.FastCode, CashoutID: bet.CashoutID, CashedOut: bet.CashedOut, BetID: bet.BetID, @@ -63,7 +64,7 @@ func (s *Store) CreateShopBet(ctx context.Context, bet domain.CreateShopBet) (do if err != nil { return domain.ShopBet{}, err } - + return convertDBShopBet(newShopBet), err } @@ -108,7 +109,7 @@ func (s *Store) GetShopBetByID(ctx context.Context, id int64) (domain.ShopBetDet fmt.Printf("GetShopBetByID Repo BetID %d err %v \n", id, err.Error()) return domain.ShopBetDetail{}, err } - + return convertDBShopBetDetail(bet), nil } diff --git a/internal/repository/user.go b/internal/repository/user.go index 8102bb6..40f620f 100644 --- a/internal/repository/user.go +++ b/internal/repository/user.go @@ -111,7 +111,7 @@ func (s *Store) GetAllUsers(ctx context.Context, filter domain.UserFilter) ([]do Valid: filter.PageSize.Valid, }, Offset: pgtype.Int4{ - Int32: int32(filter.Page.Value), + Int32: int32(filter.Page.Value * filter.PageSize.Value), Valid: filter.Page.Valid, }, Query: pgtype.Text{ diff --git a/internal/repository/virtual_game.go b/internal/repository/virtual_game.go index ab93c29..c792801 100644 --- a/internal/repository/virtual_game.go +++ b/internal/repository/virtual_game.go @@ -4,7 +4,6 @@ import ( "context" "database/sql" "errors" - "fmt" dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" @@ -30,7 +29,7 @@ type VirtualGameRepository interface { RemoveFavoriteGame(ctx context.Context, userID, gameID int64) error ListFavoriteGames(ctx context.Context, userID int64) ([]int64, error) - GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) + // GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) GetUserGameHistory(ctx context.Context, userID int64) ([]domain.VirtualGameHistory, error) CreateVirtualGameHistory(ctx context.Context, his *domain.VirtualGameHistory) error @@ -255,36 +254,36 @@ func (r *VirtualGameRepo) UpdateVirtualGameTransactionStatus(ctx context.Context }) } -func (r *VirtualGameRepo) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) { - query := `SELECT - COUNT(*) as total, - COUNT(CASE WHEN is_active = true THEN 1 END) as active, - COUNT(CASE WHEN is_active = false THEN 1 END) as inactive - FROM virtual_games` +// func (r *VirtualGameRepo) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) { +// query := `SELECT +// COUNT(*) as total, +// COUNT(CASE WHEN is_active = true THEN 1 END) as active, +// COUNT(CASE WHEN is_active = false THEN 1 END) as inactive +// FROM virtual_games` - args := []interface{}{} - argPos := 1 +// args := []interface{}{} +// argPos := 1 - // Add filters if provided - if filter.StartTime.Valid { - query += fmt.Sprintf(" WHERE created_at >= $%d", argPos) - args = append(args, filter.StartTime.Value) - argPos++ - } - if filter.EndTime.Valid { - query += fmt.Sprintf(" AND created_at <= $%d", argPos) - args = append(args, filter.EndTime.Value) - argPos++ - } +// // Add filters if provided +// if filter.StartTime.Valid { +// query += fmt.Sprintf(" WHERE created_at >= $%d", argPos) +// args = append(args, filter.StartTime.Value) +// argPos++ +// } +// if filter.EndTime.Valid { +// query += fmt.Sprintf(" AND created_at <= $%d", argPos) +// args = append(args, filter.EndTime.Value) +// argPos++ +// } - row := r.store.conn.QueryRow(ctx, query, args...) - err = row.Scan(&total, &active, &inactive) - if err != nil { - return 0, 0, 0, fmt.Errorf("failed to get game counts: %w", err) - } +// row := r.store.conn.QueryRow(ctx, query, args...) +// err = row.Scan(&total, &active, &inactive) +// if err != nil { +// return 0, 0, 0, fmt.Errorf("failed to get game counts: %w", err) +// } - return total, active, inactive, nil -} +// return total, active, inactive, nil +// } func (r *VirtualGameRepo) GetUserGameHistory(ctx context.Context, userID int64) ([]domain.VirtualGameHistory, error) { query := `SELECT game_id FROM virtual_game_histories WHERE user_id = $1 AND transaction_type = 'BET' ORDER BY created_at DESC LIMIT 100` @@ -315,4 +314,3 @@ func (r *VirtualGameRepo) ListAllVirtualGames(ctx context.Context, arg dbgen.Get func (r *VirtualGameRepo) RemoveAllVirtualGames(ctx context.Context) error { return r.store.queries.DeleteAllVirtualGames(ctx) } - diff --git a/internal/repository/wallet.go b/internal/repository/wallet.go index 6aa8d4d..02767ef 100644 --- a/internal/repository/wallet.go +++ b/internal/repository/wallet.go @@ -71,6 +71,9 @@ func convertDBGetCustomerWallet(customerWallet dbgen.CustomerWalletDetail) domai func (s *Store) CreateWallet(ctx context.Context, wallet domain.CreateWallet) (domain.Wallet, error) { newWallet, err := s.queries.CreateWallet(ctx, convertCreateWallet(wallet)) if err != nil { + if IsUniqueViolation(err) { + return domain.Wallet{}, domain.ErrWalletIDDuplicate + } return domain.Wallet{}, err } return convertDBWallet(newWallet), nil diff --git a/internal/services/company/port.go b/internal/services/company/port.go index d3540f2..3f43db8 100644 --- a/internal/services/company/port.go +++ b/internal/services/company/port.go @@ -12,7 +12,7 @@ type CompanyStore interface { SearchCompanyByName(ctx context.Context, name string) ([]domain.GetCompany, error) GetCompanyByID(ctx context.Context, id int64) (domain.GetCompany, error) GetCompanyBySlug(ctx context.Context, slug string) (domain.Company, error) - UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error) + UpdateCompany(ctx context.Context, company domain.UpdateCompany) (error) DeleteCompany(ctx context.Context, id int64) error GetCompanyCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) diff --git a/internal/services/company/service.go b/internal/services/company/service.go index 1f69a22..2dd6624 100644 --- a/internal/services/company/service.go +++ b/internal/services/company/service.go @@ -34,7 +34,7 @@ func (s *Service) SearchCompanyByName(ctx context.Context, name string) ([]domai return s.companyStore.SearchCompanyByName(ctx, name) } -func (s *Service) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (domain.Company, error) { +func (s *Service) UpdateCompany(ctx context.Context, company domain.UpdateCompany) (error) { return s.companyStore.UpdateCompany(ctx, company) } func (s *Service) DeleteCompany(ctx context.Context, id int64) error { diff --git a/internal/services/league/port.go b/internal/services/league/port.go index 277f602..31d38d2 100644 --- a/internal/services/league/port.go +++ b/internal/services/league/port.go @@ -9,7 +9,7 @@ import ( type Service interface { SaveLeague(ctx context.Context, league domain.CreateLeague) error SaveLeagueSettings(ctx context.Context, leagueSettings domain.CreateLeagueSettings) error - GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error) + GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, int64, error) GetAllLeaguesByCompany(ctx context.Context, companyID int64, filter domain.LeagueFilter) ([]domain.LeagueWithSettings, int64, error) CheckLeagueSupport(ctx context.Context, leagueID int64, companyID int64) (bool, error) UpdateLeague(ctx context.Context, league domain.UpdateLeague) error diff --git a/internal/services/league/service.go b/internal/services/league/service.go index b07bc99..0e40604 100644 --- a/internal/services/league/service.go +++ b/internal/services/league/service.go @@ -25,7 +25,7 @@ func (s *service) SaveLeagueSettings(ctx context.Context, leagueSettings domain. return s.store.SaveLeagueSettings(ctx, leagueSettings) } -func (s *service) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, error) { +func (s *service) GetAllLeagues(ctx context.Context, filter domain.LeagueFilter) ([]domain.BaseLeague, int64, error) { return s.store.GetAllLeagues(ctx, filter) } @@ -43,4 +43,4 @@ func (s *service) UpdateLeague(ctx context.Context, league domain.UpdateLeague) func (s *service) UpdateGlobalLeagueSettings(ctx context.Context, league domain.UpdateGlobalLeagueSettings) error { return s.store.UpdateGlobalLeagueSettings(ctx, league) -} \ No newline at end of file +} diff --git a/internal/services/report/service.go b/internal/services/report/service.go index 1454bae..d19cef3 100644 --- a/internal/services/report/service.go +++ b/internal/services/report/service.go @@ -135,11 +135,11 @@ func (s *Service) GetDashboardSummary(ctx context.Context, filter domain.ReportF } // Get sport/game metrics - summary.TotalGames, summary.ActiveGames, summary.InactiveGames, err = s.virtulaGamesStore.GetGameCounts(ctx, filter) - if err != nil { - s.logger.Error("failed to get game counts", "error", err) - return domain.DashboardSummary{}, err - } + // summary.TotalGames, summary.ActiveGames, summary.InactiveGames, err = s.virtulaGamesStore.GetGameCounts(ctx, filter) + // if err != nil { + // s.logger.Error("failed to get game counts", "error", err) + // return domain.DashboardSummary{}, err + // } // Get company metrics summary.TotalCompanies, summary.ActiveCompanies, summary.InactiveCompanies, err = s.companyStore.GetCompanyCounts(ctx, filter) diff --git a/internal/services/virtualGame/port.go b/internal/services/virtualGame/port.go index ca320e1..8121ea1 100644 --- a/internal/services/virtualGame/port.go +++ b/internal/services/virtualGame/port.go @@ -23,7 +23,7 @@ type VirtualGameService interface { ProcessTournamentWin(ctx context.Context, req *domain.PopOKWinRequest) (*domain.PopOKWinResponse, error) ProcessPromoWin(ctx context.Context, req *domain.PopOKWinRequest) (*domain.PopOKWinResponse, error) - GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) + // GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) ListGames(ctx context.Context, currency string) ([]domain.PopOKGame, error) RecommendGames(ctx context.Context, userID int64) ([]domain.GameRecommendation, error) AddFavoriteGame(ctx context.Context, userID, gameID int64) error diff --git a/internal/services/virtualGame/service.go b/internal/services/virtualGame/service.go index 3cd1fb8..46ddb66 100644 --- a/internal/services/virtualGame/service.go +++ b/internal/services/virtualGame/service.go @@ -657,9 +657,9 @@ func (s *service) verifySignature(callback *domain.PopOKCallback) bool { return expected == callback.Signature } -func (s *service) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) { - return s.repo.GetGameCounts(ctx, filter) -} +// func (s *service) GetGameCounts(ctx context.Context, filter domain.ReportFilter) (total, active, inactive int64, err error) { +// return s.repo.GetGameCounts(ctx, filter) +// } func (s *service) ListGames(ctx context.Context, currency string) ([]domain.PopOKGame, error) { now := time.Now().Format("02-01-2006 15:04:05") // dd-mm-yyyy hh:mm:ss diff --git a/internal/web_server/cron.go b/internal/web_server/cron.go index 09aab85..a03c34b 100644 --- a/internal/web_server/cron.go +++ b/internal/web_server/cron.go @@ -95,7 +95,7 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S } for _, job := range schedule { - // job.task() + job.task() if _, err := c.AddFunc(job.spec, job.task); err != nil { mongoLogger.Error("Failed to schedule data fetching cron job", zap.Error(err), diff --git a/internal/web_server/handlers/admin.go b/internal/web_server/handlers/admin.go index b7bd75e..036f96a 100644 --- a/internal/web_server/handlers/admin.go +++ b/internal/web_server/handlers/admin.go @@ -103,25 +103,25 @@ func (h *Handler) CreateAdmin(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusInternalServerError, "Failed to create admin:"+err.Error()) } - if req.CompanyID != nil { - _, err := h.companySvc.UpdateCompany(c.Context(), domain.UpdateCompany{ - ID: *req.CompanyID, - AdminID: domain.ValidInt64{ - Value: newUser.ID, - Valid: true, - }, - }) - if err != nil { - h.mongoLoggerSvc.Error("failed to update company with new admin", - zap.Int64("status_code", fiber.StatusInternalServerError), - zap.Int64("company_id", *req.CompanyID), - zap.Int64("admin_id", newUser.ID), - zap.Error(err), - zap.Time("timestamp", time.Now()), - ) - return fiber.NewError(fiber.StatusInternalServerError, "Failed to update company"+err.Error()) - } - } + // if req.CompanyID != nil { + // _, err := h.companySvc.UpdateCompany(c.Context(), domain.UpdateCompany{ + // ID: *req.CompanyID, + // AdminID: domain.ValidInt64{ + // Value: newUser.ID, + // Valid: true, + // }, + // }) + // if err != nil { + // h.mongoLoggerSvc.Error("failed to update company with new admin", + // zap.Int64("status_code", fiber.StatusInternalServerError), + // zap.Int64("company_id", *req.CompanyID), + // zap.Int64("admin_id", newUser.ID), + // zap.Error(err), + // zap.Time("timestamp", time.Now()), + // ) + // return fiber.NewError(fiber.StatusInternalServerError, "Failed to update company"+err.Error()) + // } + // } h.mongoLoggerSvc.Info("admin created successfully", zap.Int64("admin_id", newUser.ID), @@ -196,7 +196,7 @@ func (h *Handler) GetAllAdmins(c *fiber.Ctx) error { Valid: true, } } - + companyFilter := int64(c.QueryInt("company_id")) filter := domain.UserFilter{ Role: string(domain.RoleAdmin), @@ -283,7 +283,7 @@ func (h *Handler) GetAllAdmins(c *fiber.Ctx) error { zap.Time("timestamp", time.Now()), ) - return response.WritePaginatedJSON(c, fiber.StatusOK, "Admins retrieved successfully", result, nil, filter.Page.Value, int(total)) + return response.WritePaginatedJSON(c, fiber.StatusOK, "Admins retrieved successfully", result, nil, filter.Page.Value+1, int(total)) } // GetAdminByID godoc diff --git a/internal/web_server/handlers/company_handler.go b/internal/web_server/handlers/company_handler.go index 64fd401..d353a29 100644 --- a/internal/web_server/handlers/company_handler.go +++ b/internal/web_server/handlers/company_handler.go @@ -1,6 +1,7 @@ package handlers import ( + "errors" "fmt" "strconv" "time" @@ -82,17 +83,31 @@ func (h *Handler) CreateCompany(c *fiber.Ctx) error { AdminID: user.ID, WalletID: newWallet.ID, DeductedPercentage: req.DeductedPercentage, + Slug: req.Slug, + IsActive: req.IsActive, }) if err != nil { + if errors.Is(err, domain.ErrWalletIDDuplicate) { + h.mongoLoggerSvc.Error("CreateCompanyReq failed to create company", + zap.Int64("userID", user.ID), + zap.String("name", req.Name), + zap.Int("status_code", fiber.StatusBadRequest), + zap.Error(err), + zap.Time("timestamp", time.Now()), + ) + + return fiber.NewError(fiber.StatusBadRequest, "this admin already has a company assigned to him") + } + h.mongoLoggerSvc.Error("CreateCompanyReq failed to create company", zap.Int64("userID", user.ID), zap.String("name", req.Name), - zap.String("Name", req.Name), zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), ) + return fiber.NewError(fiber.StatusInternalServerError, err.Error()) } @@ -361,11 +376,12 @@ func (h *Handler) UpdateCompany(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusBadRequest, errMsg) } - company, err := h.companySvc.UpdateCompany(c.Context(), domain.ConvertUpdateCompanyReq(req)) + err = h.companySvc.UpdateCompany(c.Context(), domain.ConvertUpdateCompanyReq(req, id)) if err != nil { h.mongoLoggerSvc.Error("Failed to update company", zap.Int64("companyID", id), + zap.Any("req", req), zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), @@ -373,9 +389,7 @@ func (h *Handler) UpdateCompany(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusInternalServerError, err.Error()) } - res := domain.ConvertCompany(company) - - return response.WriteJSON(c, fiber.StatusOK, "Company Updated", res, nil) + return response.WriteJSON(c, fiber.StatusOK, "Company Updated", nil, nil) } diff --git a/internal/web_server/handlers/leagues.go b/internal/web_server/handlers/leagues.go index 08c15a9..f801df8 100644 --- a/internal/web_server/handlers/leagues.go +++ b/internal/web_server/handlers/leagues.go @@ -86,7 +86,7 @@ func (h *Handler) GetAllLeagues(c *fiber.Ctx) error { zap.Bool("sport_id_valid", sportID.Valid), } - leagues, err := h.leagueSvc.GetAllLeagues(c.Context(), domain.LeagueFilter{ + leagues, total, err := h.leagueSvc.GetAllLeagues(c.Context(), domain.LeagueFilter{ CountryCode: countryCode, IsActive: isActive, SportID: sportID, @@ -104,7 +104,7 @@ func (h *Handler) GetAllLeagues(c *fiber.Ctx) error { res := domain.ConvertBaseLeagueResList(leagues) - return response.WriteJSON(c, fiber.StatusOK, "All leagues retrieved", res, nil) + return response.WritePaginatedJSON(c, fiber.StatusOK, "All leagues retrieved successfully", res, nil, page, int(total)) } // GetAllLeaguesForTenant godoc diff --git a/internal/web_server/handlers/user.go b/internal/web_server/handlers/user.go index fe89de9..8d36762 100644 --- a/internal/web_server/handlers/user.go +++ b/internal/web_server/handlers/user.go @@ -328,9 +328,9 @@ func (h *Handler) RegisterUser(c *fiber.Ctx) error { } // TODO: Remove later - _, err = h.walletSvc.AddToWallet( - c.Context(), newWallet.RegularID, domain.ToCurrency(10000.0), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}, - "Added 10000.0 to wallet only as test for deployment") + // _, err = h.walletSvc.AddToWallet( + // c.Context(), newWallet.RegularID, domain.ToCurrency(10000.0), domain.ValidInt64{}, domain.TRANSFER_DIRECT, domain.PaymentDetails{}, + // "Added 10000.0 to wallet only as test for deployment") if err != nil { h.mongoLoggerSvc.Error("Failed to update wallet for user",