feat: added bet and ticket handlers
This commit is contained in:
parent
0c38426549
commit
959390b506
10
cmd/main.go
10
cmd/main.go
|
|
@ -11,6 +11,8 @@ import (
|
||||||
mocksms "github.com/SamuelTariku/FortuneBet-Backend/internal/mocks/mock_sms"
|
mocksms "github.com/SamuelTariku/FortuneBet-Backend/internal/mocks/mock_sms"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/repository"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
||||||
httpserver "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server"
|
httpserver "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server"
|
||||||
jwtutil "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/jwt"
|
jwtutil "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/jwt"
|
||||||
|
|
@ -46,16 +48,22 @@ func main() {
|
||||||
logger := customlogger.NewLogger(cfg.Env, cfg.LogLevel)
|
logger := customlogger.NewLogger(cfg.Env, cfg.LogLevel)
|
||||||
store := repository.NewStore(db)
|
store := repository.NewStore(db)
|
||||||
v := customvalidator.NewCustomValidator(validator.New())
|
v := customvalidator.NewCustomValidator(validator.New())
|
||||||
|
|
||||||
authSvc := authentication.NewService(store, store, cfg.RefreshExpiry)
|
authSvc := authentication.NewService(store, store, cfg.RefreshExpiry)
|
||||||
mockSms := mocksms.NewMockSMS()
|
mockSms := mocksms.NewMockSMS()
|
||||||
mockemail := mockemail.NewMockEmail()
|
mockemail := mockemail.NewMockEmail()
|
||||||
|
|
||||||
userSvc := user.NewService(store, store, mockSms, mockemail)
|
userSvc := user.NewService(store, store, mockSms, mockemail)
|
||||||
|
ticketSvc := ticket.NewService(store)
|
||||||
|
betSvc := bet.NewService(store)
|
||||||
|
|
||||||
app := httpserver.NewApp(cfg.Port, v, authSvc, logger, jwtutil.JwtConfig{
|
app := httpserver.NewApp(cfg.Port, v, authSvc, logger, jwtutil.JwtConfig{
|
||||||
JwtAccessKey: cfg.JwtKey,
|
JwtAccessKey: cfg.JwtKey,
|
||||||
JwtAccessExpiry: cfg.AccessExpiry,
|
JwtAccessExpiry: cfg.AccessExpiry,
|
||||||
}, userSvc,
|
}, userSvc, ticketSvc, betSvc,
|
||||||
)
|
)
|
||||||
logger.Info("Starting server", "port", cfg.Port)
|
logger.Info("Starting server", "port", cfg.Port)
|
||||||
|
|
||||||
if err := app.Run(); err != nil {
|
if err := app.Run(); err != nil {
|
||||||
logger.Error("Failed to start server", "error", err)
|
logger.Error("Failed to start server", "error", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,44 @@ CREATE TABLE refresh_tokens (
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
expires_at TIMESTAMPTZ NOT NULL
|
expires_at TIMESTAMPTZ NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS bets (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
amount BIGINT NOT NULL,
|
||||||
|
total_odds REAL NOT NULL,
|
||||||
|
status INT NOT NULL,
|
||||||
|
full_name VARCHAR(255) NOT NULL,
|
||||||
|
phone_number VARCHAR(255) NOT NULL,
|
||||||
|
branch_id BIGINT,
|
||||||
|
user_id BIGINT,
|
||||||
|
cashed_out BOOLEAN DEFAULT FALSE,
|
||||||
|
created_at TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP,
|
||||||
|
is_shop_bet BOOLEAN NOT NULL,
|
||||||
|
CHECK (user_id IS NOT NULL OR branch_id IS NOT NULL)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS tickets (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
amount BIGINT NULL,
|
||||||
|
total_odds REAL NOT NULL,
|
||||||
|
created_at TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
-- CREATE TABLE IF NOT EXISTS bet_outcomes (
|
||||||
|
-- id BIGSERIAL PRIMARY KEY,
|
||||||
|
-- bet_id BIGINT NOT NULL,
|
||||||
|
-- outcome_id BIGINT NOT NULL,
|
||||||
|
-- );
|
||||||
|
|
||||||
|
-- CREATE TABLE IF NOT EXISTS ticket_outcomes (
|
||||||
|
-- id BIGSERIAL PRIMARY KEY,
|
||||||
|
-- ticket_id BIGINT NOT NULL,
|
||||||
|
-- outcome_id BIGINT NOT NULL,
|
||||||
|
-- );
|
||||||
|
|
||||||
----------------------------------------------seed data-------------------------------------------------------------
|
----------------------------------------------seed data-------------------------------------------------------------
|
||||||
-------------------------------------- DO NOT USE IN PRODUCTION-------------------------------------------------
|
-------------------------------------- DO NOT USE IN PRODUCTION-------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -61,38 +99,3 @@ INSERT INTO users (
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS bets (
|
|
||||||
id BIGSERIAL PRIMARY KEY,
|
|
||||||
amount BIGINT NOT NULL,
|
|
||||||
total_odds REAL NOT NULL,
|
|
||||||
status INT NOT NULL,
|
|
||||||
full_name VARCHAR(255) NOT NULL,
|
|
||||||
phone_number VARCHAR(255) NOT NULL,
|
|
||||||
branch_id BIGINT,
|
|
||||||
user_id BIGINT,
|
|
||||||
cashed_out BOOLEAN DEFAULT FALSE,
|
|
||||||
created_at TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP,
|
|
||||||
CHECK (user_id IS NOT NULL OR branch_id IS NOT NULL)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS tickets (
|
|
||||||
id BIGSERIAL PRIMARY KEY,
|
|
||||||
amount BIGINT NULL,
|
|
||||||
total_odds REAL NOT NULL,
|
|
||||||
created_at TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
-- CREATE TABLE IF NOT EXISTS bet_outcomes (
|
|
||||||
-- id BIGSERIAL PRIMARY KEY,
|
|
||||||
-- bet_id BIGINT NOT NULL,
|
|
||||||
-- outcome_id BIGINT NOT NULL,
|
|
||||||
-- );
|
|
||||||
|
|
||||||
-- CREATE TABLE IF NOT EXISTS ticket_outcomes (
|
|
||||||
-- id BIGSERIAL PRIMARY KEY,
|
|
||||||
-- ticket_id BIGINT NOT NULL,
|
|
||||||
-- outcome_id BIGINT NOT NULL,
|
|
||||||
-- );
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
-- name: CreateBet :one
|
-- name: CreateBet :one
|
||||||
INSERT INTO bets (amount, total_odds, status, full_name, phone_number, branch_id, user_id)
|
INSERT INTO bets (amount, total_odds, status, full_name, phone_number, branch_id, user_id, is_shop_bet)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: GetAllBets :many
|
-- name: GetAllBets :many
|
||||||
|
|
|
||||||
512
docs/docs.go
512
docs/docs.go
|
|
@ -180,6 +180,351 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/bet": {
|
||||||
|
"get": {
|
||||||
|
"description": "Gets all the bets",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"bet"
|
||||||
|
],
|
||||||
|
"summary": "Gets all bets",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/handlers.BetRes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"description": "Creates a bet",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"bet"
|
||||||
|
],
|
||||||
|
"summary": "Create a bet",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Creates bet",
|
||||||
|
"name": "createBet",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.CreateBetReq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.BetRes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/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/handlers.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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patch": {
|
||||||
|
"description": "Updates the cashed out field",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"bet"
|
||||||
|
],
|
||||||
|
"summary": "Updates the cashed out field",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Bet ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Updates Cashed Out",
|
||||||
|
"name": "updateCashOut",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.UpdateCashOutReq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/ticket": {
|
||||||
|
"get": {
|
||||||
|
"description": "Retrieve all tickets",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"ticket"
|
||||||
|
],
|
||||||
|
"summary": "Get all tickets",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/handlers.TicketRes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"description": "Creates a temporary ticket",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"ticket"
|
||||||
|
],
|
||||||
|
"summary": "Create a temporary ticket",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Creates ticket",
|
||||||
|
"name": "createTicket",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.CreateTicketReq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.CreateTicketRes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/ticket/{id}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Retrieve ticket details by ticket ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"ticket"
|
||||||
|
],
|
||||||
|
"summary": "Get ticket by ID",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Ticket ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.TicketRes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/user/checkPhoneEmailExist": {
|
"/user/checkPhoneEmailExist": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Check if phone number or email exist",
|
"description": "Check if phone number or email exist",
|
||||||
|
|
@ -452,6 +797,24 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
"domain.BetStatus": {
|
||||||
|
"type": "integer",
|
||||||
|
"enum": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"x-enum-varnames": [
|
||||||
|
"BET_STATUS_PENDING",
|
||||||
|
"BET_STATUS_WIN",
|
||||||
|
"BET_STATUS_LOSS",
|
||||||
|
"BET_STATUS_ERROR"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"domain.Outcome": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"domain.Role": {
|
"domain.Role": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
|
@ -469,6 +832,57 @@ const docTemplate = `{
|
||||||
"RoleCashier"
|
"RoleCashier"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"handlers.BetRes": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"amount": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 100
|
||||||
|
},
|
||||||
|
"branch_id": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 2
|
||||||
|
},
|
||||||
|
"full_name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "John"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"is_shop_bet": {
|
||||||
|
"type": "boolean",
|
||||||
|
"example": false
|
||||||
|
},
|
||||||
|
"outcomes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/domain.Outcome"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"phone_number": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "1234567890"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/domain.BetStatus"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"total_odds": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 4.22
|
||||||
|
},
|
||||||
|
"user_id": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"handlers.CheckPhoneEmailExistReq": {
|
"handlers.CheckPhoneEmailExistReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -493,6 +907,73 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"handlers.CreateBetReq": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"amount": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 100
|
||||||
|
},
|
||||||
|
"full_name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "John"
|
||||||
|
},
|
||||||
|
"is_shop_bet": {
|
||||||
|
"type": "boolean",
|
||||||
|
"example": false
|
||||||
|
},
|
||||||
|
"outcomes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"phone_number": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "1234567890"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/domain.BetStatus"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"total_odds": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 4.22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"handlers.CreateTicketReq": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"amount": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 100
|
||||||
|
},
|
||||||
|
"outcomes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"total_odds": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 4.22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"handlers.CreateTicketRes": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"fast_code": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1234
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"handlers.RegisterCodeReq": {
|
"handlers.RegisterCodeReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -570,6 +1051,37 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"handlers.TicketRes": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"amount": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 100
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"outcomes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/domain.Outcome"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"total_odds": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 4.22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"handlers.UpdateCashOutReq": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"cashedOut": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"handlers.UserProfileRes": {
|
"handlers.UserProfileRes": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,351 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/bet": {
|
||||||
|
"get": {
|
||||||
|
"description": "Gets all the bets",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"bet"
|
||||||
|
],
|
||||||
|
"summary": "Gets all bets",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/handlers.BetRes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"description": "Creates a bet",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"bet"
|
||||||
|
],
|
||||||
|
"summary": "Create a bet",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Creates bet",
|
||||||
|
"name": "createBet",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.CreateBetReq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.BetRes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/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/handlers.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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patch": {
|
||||||
|
"description": "Updates the cashed out field",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"bet"
|
||||||
|
],
|
||||||
|
"summary": "Updates the cashed out field",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Bet ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Updates Cashed Out",
|
||||||
|
"name": "updateCashOut",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.UpdateCashOutReq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/ticket": {
|
||||||
|
"get": {
|
||||||
|
"description": "Retrieve all tickets",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"ticket"
|
||||||
|
],
|
||||||
|
"summary": "Get all tickets",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/handlers.TicketRes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"description": "Creates a temporary ticket",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"ticket"
|
||||||
|
],
|
||||||
|
"summary": "Create a temporary ticket",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Creates ticket",
|
||||||
|
"name": "createTicket",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.CreateTicketReq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.CreateTicketRes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/ticket/{id}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Retrieve ticket details by ticket ID",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"ticket"
|
||||||
|
],
|
||||||
|
"summary": "Get ticket by ID",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Ticket ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/handlers.TicketRes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Request",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.APIResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/user/checkPhoneEmailExist": {
|
"/user/checkPhoneEmailExist": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Check if phone number or email exist",
|
"description": "Check if phone number or email exist",
|
||||||
|
|
@ -444,6 +789,24 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
"domain.BetStatus": {
|
||||||
|
"type": "integer",
|
||||||
|
"enum": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"x-enum-varnames": [
|
||||||
|
"BET_STATUS_PENDING",
|
||||||
|
"BET_STATUS_WIN",
|
||||||
|
"BET_STATUS_LOSS",
|
||||||
|
"BET_STATUS_ERROR"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"domain.Outcome": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"domain.Role": {
|
"domain.Role": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
|
@ -461,6 +824,57 @@
|
||||||
"RoleCashier"
|
"RoleCashier"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"handlers.BetRes": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"amount": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 100
|
||||||
|
},
|
||||||
|
"branch_id": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 2
|
||||||
|
},
|
||||||
|
"full_name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "John"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"is_shop_bet": {
|
||||||
|
"type": "boolean",
|
||||||
|
"example": false
|
||||||
|
},
|
||||||
|
"outcomes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/domain.Outcome"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"phone_number": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "1234567890"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/domain.BetStatus"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"total_odds": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 4.22
|
||||||
|
},
|
||||||
|
"user_id": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"handlers.CheckPhoneEmailExistReq": {
|
"handlers.CheckPhoneEmailExistReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -485,6 +899,73 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"handlers.CreateBetReq": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"amount": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 100
|
||||||
|
},
|
||||||
|
"full_name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "John"
|
||||||
|
},
|
||||||
|
"is_shop_bet": {
|
||||||
|
"type": "boolean",
|
||||||
|
"example": false
|
||||||
|
},
|
||||||
|
"outcomes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"phone_number": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "1234567890"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/domain.BetStatus"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"total_odds": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 4.22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"handlers.CreateTicketReq": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"amount": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 100
|
||||||
|
},
|
||||||
|
"outcomes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"total_odds": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 4.22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"handlers.CreateTicketRes": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"fast_code": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1234
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"handlers.RegisterCodeReq": {
|
"handlers.RegisterCodeReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
@ -562,6 +1043,37 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"handlers.TicketRes": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"amount": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 100
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 1
|
||||||
|
},
|
||||||
|
"outcomes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/domain.Outcome"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"total_odds": {
|
||||||
|
"type": "number",
|
||||||
|
"example": 4.22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"handlers.UpdateCashOutReq": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"cashedOut": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"handlers.UserProfileRes": {
|
"handlers.UserProfileRes": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,18 @@
|
||||||
definitions:
|
definitions:
|
||||||
|
domain.BetStatus:
|
||||||
|
enum:
|
||||||
|
- 0
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
- 3
|
||||||
|
type: integer
|
||||||
|
x-enum-varnames:
|
||||||
|
- BET_STATUS_PENDING
|
||||||
|
- BET_STATUS_WIN
|
||||||
|
- BET_STATUS_LOSS
|
||||||
|
- BET_STATUS_ERROR
|
||||||
|
domain.Outcome:
|
||||||
|
type: object
|
||||||
domain.Role:
|
domain.Role:
|
||||||
enum:
|
enum:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -13,6 +27,41 @@ definitions:
|
||||||
- RoleSuperAdmin
|
- RoleSuperAdmin
|
||||||
- RoleBranchManager
|
- RoleBranchManager
|
||||||
- RoleCashier
|
- RoleCashier
|
||||||
|
handlers.BetRes:
|
||||||
|
properties:
|
||||||
|
amount:
|
||||||
|
example: 100
|
||||||
|
type: number
|
||||||
|
branch_id:
|
||||||
|
example: 2
|
||||||
|
type: integer
|
||||||
|
full_name:
|
||||||
|
example: John
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
example: 1
|
||||||
|
type: integer
|
||||||
|
is_shop_bet:
|
||||||
|
example: false
|
||||||
|
type: boolean
|
||||||
|
outcomes:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/domain.Outcome'
|
||||||
|
type: array
|
||||||
|
phone_number:
|
||||||
|
example: "1234567890"
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/domain.BetStatus'
|
||||||
|
example: 1
|
||||||
|
total_odds:
|
||||||
|
example: 4.22
|
||||||
|
type: number
|
||||||
|
user_id:
|
||||||
|
example: 2
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
handlers.CheckPhoneEmailExistReq:
|
handlers.CheckPhoneEmailExistReq:
|
||||||
properties:
|
properties:
|
||||||
email:
|
email:
|
||||||
|
|
@ -29,6 +78,51 @@ definitions:
|
||||||
phone_number_exist:
|
phone_number_exist:
|
||||||
type: boolean
|
type: boolean
|
||||||
type: object
|
type: object
|
||||||
|
handlers.CreateBetReq:
|
||||||
|
properties:
|
||||||
|
amount:
|
||||||
|
example: 100
|
||||||
|
type: number
|
||||||
|
full_name:
|
||||||
|
example: John
|
||||||
|
type: string
|
||||||
|
is_shop_bet:
|
||||||
|
example: false
|
||||||
|
type: boolean
|
||||||
|
outcomes:
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
type: array
|
||||||
|
phone_number:
|
||||||
|
example: "1234567890"
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/domain.BetStatus'
|
||||||
|
example: 1
|
||||||
|
total_odds:
|
||||||
|
example: 4.22
|
||||||
|
type: number
|
||||||
|
type: object
|
||||||
|
handlers.CreateTicketReq:
|
||||||
|
properties:
|
||||||
|
amount:
|
||||||
|
example: 100
|
||||||
|
type: number
|
||||||
|
outcomes:
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
type: array
|
||||||
|
total_odds:
|
||||||
|
example: 4.22
|
||||||
|
type: number
|
||||||
|
type: object
|
||||||
|
handlers.CreateTicketRes:
|
||||||
|
properties:
|
||||||
|
fast_code:
|
||||||
|
example: 1234
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
handlers.RegisterCodeReq:
|
handlers.RegisterCodeReq:
|
||||||
properties:
|
properties:
|
||||||
email:
|
email:
|
||||||
|
|
@ -83,6 +177,27 @@ definitions:
|
||||||
phoneNumber:
|
phoneNumber:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
|
handlers.TicketRes:
|
||||||
|
properties:
|
||||||
|
amount:
|
||||||
|
example: 100
|
||||||
|
type: number
|
||||||
|
id:
|
||||||
|
example: 1
|
||||||
|
type: integer
|
||||||
|
outcomes:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/domain.Outcome'
|
||||||
|
type: array
|
||||||
|
total_odds:
|
||||||
|
example: 4.22
|
||||||
|
type: number
|
||||||
|
type: object
|
||||||
|
handlers.UpdateCashOutReq:
|
||||||
|
properties:
|
||||||
|
cashedOut:
|
||||||
|
type: boolean
|
||||||
|
type: object
|
||||||
handlers.UserProfileRes:
|
handlers.UserProfileRes:
|
||||||
properties:
|
properties:
|
||||||
created_at:
|
created_at:
|
||||||
|
|
@ -275,6 +390,234 @@ paths:
|
||||||
summary: Refresh token
|
summary: Refresh token
|
||||||
tags:
|
tags:
|
||||||
- auth
|
- auth
|
||||||
|
/bet:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Gets all the bets
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/handlers.BetRes'
|
||||||
|
type: array
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
summary: Gets all bets
|
||||||
|
tags:
|
||||||
|
- bet
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Creates a bet
|
||||||
|
parameters:
|
||||||
|
- description: Creates bet
|
||||||
|
in: body
|
||||||
|
name: createBet
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/handlers.CreateBetReq'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/handlers.BetRes'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
summary: Create a bet
|
||||||
|
tags:
|
||||||
|
- bet
|
||||||
|
/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/handlers.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
|
||||||
|
patch:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Updates the cashed out field
|
||||||
|
parameters:
|
||||||
|
- description: Bet ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
- description: Updates Cashed Out
|
||||||
|
in: body
|
||||||
|
name: updateCashOut
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/handlers.UpdateCashOutReq'
|
||||||
|
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: Updates the cashed out field
|
||||||
|
tags:
|
||||||
|
- bet
|
||||||
|
/ticket:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Retrieve all tickets
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/handlers.TicketRes'
|
||||||
|
type: array
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
summary: Get all tickets
|
||||||
|
tags:
|
||||||
|
- ticket
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Creates a temporary ticket
|
||||||
|
parameters:
|
||||||
|
- description: Creates ticket
|
||||||
|
in: body
|
||||||
|
name: createTicket
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/handlers.CreateTicketReq'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/handlers.CreateTicketRes'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
summary: Create a temporary ticket
|
||||||
|
tags:
|
||||||
|
- ticket
|
||||||
|
/ticket/{id}:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: Retrieve ticket details by ticket ID
|
||||||
|
parameters:
|
||||||
|
- description: Ticket ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/handlers.TicketRes'
|
||||||
|
"400":
|
||||||
|
description: Bad Request
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.APIResponse'
|
||||||
|
summary: Get ticket by ID
|
||||||
|
tags:
|
||||||
|
- ticket
|
||||||
/user/checkPhoneEmailExist:
|
/user/checkPhoneEmailExist:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.26.0
|
// sqlc v1.28.0
|
||||||
// source: auth.sql
|
// source: auth.sql
|
||||||
|
|
||||||
package dbgen
|
package dbgen
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const CreateBet = `-- name: CreateBet :one
|
const CreateBet = `-- name: CreateBet :one
|
||||||
INSERT INTO bets (amount, total_odds, status, full_name, phone_number, branch_id, user_id)
|
INSERT INTO bets (amount, total_odds, status, full_name, phone_number, branch_id, user_id, is_shop_bet)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||||
RETURNING id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, created_at, updated_at
|
RETURNING id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, created_at, updated_at, is_shop_bet
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateBetParams struct {
|
type CreateBetParams struct {
|
||||||
|
|
@ -25,6 +25,7 @@ type CreateBetParams struct {
|
||||||
PhoneNumber string
|
PhoneNumber string
|
||||||
BranchID pgtype.Int8
|
BranchID pgtype.Int8
|
||||||
UserID pgtype.Int8
|
UserID pgtype.Int8
|
||||||
|
IsShopBet bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, error) {
|
func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, error) {
|
||||||
|
|
@ -36,6 +37,7 @@ func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, erro
|
||||||
arg.PhoneNumber,
|
arg.PhoneNumber,
|
||||||
arg.BranchID,
|
arg.BranchID,
|
||||||
arg.UserID,
|
arg.UserID,
|
||||||
|
arg.IsShopBet,
|
||||||
)
|
)
|
||||||
var i Bet
|
var i Bet
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
|
|
@ -50,6 +52,7 @@ func (q *Queries) CreateBet(ctx context.Context, arg CreateBetParams) (Bet, erro
|
||||||
&i.CashedOut,
|
&i.CashedOut,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.IsShopBet,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +67,7 @@ func (q *Queries) DeleteBet(ctx context.Context, id int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetAllBets = `-- name: GetAllBets :many
|
const GetAllBets = `-- name: GetAllBets :many
|
||||||
SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, created_at, updated_at FROM bets
|
SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, created_at, updated_at, is_shop_bet FROM bets
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetAllBets(ctx context.Context) ([]Bet, error) {
|
func (q *Queries) GetAllBets(ctx context.Context) ([]Bet, error) {
|
||||||
|
|
@ -88,6 +91,7 @@ func (q *Queries) GetAllBets(ctx context.Context) ([]Bet, error) {
|
||||||
&i.CashedOut,
|
&i.CashedOut,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.IsShopBet,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +104,7 @@ func (q *Queries) GetAllBets(ctx context.Context) ([]Bet, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const GetBetByID = `-- name: GetBetByID :one
|
const GetBetByID = `-- name: GetBetByID :one
|
||||||
SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, created_at, updated_at FROM bets WHERE id = $1
|
SELECT id, amount, total_odds, status, full_name, phone_number, branch_id, user_id, cashed_out, created_at, updated_at, is_shop_bet FROM bets WHERE id = $1
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetBetByID(ctx context.Context, id int64) (Bet, error) {
|
func (q *Queries) GetBetByID(ctx context.Context, id int64) (Bet, error) {
|
||||||
|
|
@ -118,6 +122,7 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (Bet, error) {
|
||||||
&i.CashedOut,
|
&i.CashedOut,
|
||||||
&i.CreatedAt,
|
&i.CreatedAt,
|
||||||
&i.UpdatedAt,
|
&i.UpdatedAt,
|
||||||
|
&i.IsShopBet,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,21 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Bet struct {
|
||||||
|
ID int64
|
||||||
|
Amount int64
|
||||||
|
TotalOdds float32
|
||||||
|
Status int32
|
||||||
|
FullName string
|
||||||
|
PhoneNumber string
|
||||||
|
BranchID pgtype.Int8
|
||||||
|
UserID pgtype.Int8
|
||||||
|
CashedOut pgtype.Bool
|
||||||
|
CreatedAt pgtype.Timestamp
|
||||||
|
UpdatedAt pgtype.Timestamp
|
||||||
|
IsShopBet bool
|
||||||
|
}
|
||||||
|
|
||||||
type Otp struct {
|
type Otp struct {
|
||||||
ID int64
|
ID int64
|
||||||
SentTo string
|
SentTo string
|
||||||
|
|
@ -29,20 +44,6 @@ type RefreshToken struct {
|
||||||
Revoked bool
|
Revoked bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Bet struct {
|
|
||||||
ID int64
|
|
||||||
Amount int64
|
|
||||||
TotalOdds float32
|
|
||||||
Status int32
|
|
||||||
FullName string
|
|
||||||
PhoneNumber string
|
|
||||||
BranchID pgtype.Int8
|
|
||||||
UserID pgtype.Int8
|
|
||||||
CashedOut pgtype.Bool
|
|
||||||
CreatedAt pgtype.Timestamp
|
|
||||||
UpdatedAt pgtype.Timestamp
|
|
||||||
}
|
|
||||||
|
|
||||||
type Ticket struct {
|
type Ticket struct {
|
||||||
ID int64
|
ID int64
|
||||||
Amount pgtype.Int8
|
Amount pgtype.Int8
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by sqlc. DO NOT EDIT.
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// sqlc v1.26.0
|
// sqlc v1.28.0
|
||||||
// source: otp.sql
|
// source: otp.sql
|
||||||
|
|
||||||
package dbgen
|
package dbgen
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,11 @@ const (
|
||||||
BET_STATUS_ERROR
|
BET_STATUS_ERROR
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// If it is a ShopBet then UserID will be the cashier
|
||||||
|
// If it is a DigitalBet then UserID will be the user and the branchID will be 0 or nil
|
||||||
type Bet struct {
|
type Bet struct {
|
||||||
ID int64
|
ID int64
|
||||||
Outcome []Outcome
|
Outcomes []Outcome
|
||||||
Amount Currency
|
Amount Currency
|
||||||
TotalOdds float32
|
TotalOdds float32
|
||||||
Status BetStatus
|
Status BetStatus
|
||||||
|
|
@ -19,9 +21,24 @@ type Bet struct {
|
||||||
PhoneNumber string
|
PhoneNumber string
|
||||||
BranchID ValidInt64 // Can Be Nullable
|
BranchID ValidInt64 // Can Be Nullable
|
||||||
UserID ValidInt64 // Can Be Nullable
|
UserID ValidInt64 // Can Be Nullable
|
||||||
|
IsShopBet bool
|
||||||
CashedOut bool
|
CashedOut bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CreateBet struct {
|
||||||
|
Outcomes []int64
|
||||||
|
Amount Currency
|
||||||
|
TotalOdds float32
|
||||||
|
Status BetStatus
|
||||||
|
FullName string
|
||||||
|
PhoneNumber string
|
||||||
|
BranchID ValidInt64 // Can Be Nullable
|
||||||
|
UserID ValidInt64 // Can Be Nullable
|
||||||
|
IsShopBet bool
|
||||||
|
}
|
||||||
|
|
||||||
func (b BetStatus) String() string {
|
func (b BetStatus) String() string {
|
||||||
return []string{"Pending", "Win", "Loss", "Error"}[b]
|
return []string{"Pending", "Win", "Loss", "Error"}[b]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func isBetStatusValid()
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,15 @@ type ValidInt64 struct {
|
||||||
Valid bool
|
Valid bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ValidString struct {
|
||||||
|
Value string
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
type ValidBool struct {
|
||||||
|
Value bool
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
|
||||||
type Currency int64
|
type Currency int64
|
||||||
|
|
||||||
// ToCurrency converts a float32 to Currency
|
// ToCurrency converts a float32 to Currency
|
||||||
|
|
@ -28,11 +37,3 @@ func (m Currency) String() string {
|
||||||
return fmt.Sprintf("$%.2f", x)
|
return fmt.Sprintf("$%.2f", x)
|
||||||
|
|
||||||
}
|
}
|
||||||
type ValidString struct {
|
|
||||||
Value string
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
type ValidBool struct {
|
|
||||||
Value bool
|
|
||||||
Valid bool
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,13 @@ package domain
|
||||||
// ID will serve as the fast code since this doesn't need to be secure
|
// ID will serve as the fast code since this doesn't need to be secure
|
||||||
type Ticket struct {
|
type Ticket struct {
|
||||||
ID int64
|
ID int64
|
||||||
Outcome []Outcome
|
Outcomes []Outcome
|
||||||
|
Amount Currency
|
||||||
|
TotalOdds float32
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateTicket struct {
|
||||||
|
Outcomes []int64
|
||||||
Amount Currency
|
Amount Currency
|
||||||
TotalOdds float32
|
TotalOdds float32
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,28 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Store) CreateBet(ctx context.Context, bet domain.Bet) (domain.Bet, error) {
|
func convertDBBet(bet dbgen.Bet) domain.Bet {
|
||||||
|
return domain.Bet{
|
||||||
|
ID: bet.ID,
|
||||||
|
Amount: domain.Currency(bet.Amount),
|
||||||
|
TotalOdds: bet.TotalOdds,
|
||||||
|
Status: domain.BetStatus(bet.Status),
|
||||||
|
FullName: bet.FullName,
|
||||||
|
PhoneNumber: bet.PhoneNumber,
|
||||||
|
BranchID: domain.ValidInt64{
|
||||||
|
Value: bet.BranchID.Int64,
|
||||||
|
Valid: bet.BranchID.Valid,
|
||||||
|
},
|
||||||
|
UserID: domain.ValidInt64{
|
||||||
|
Value: bet.UserID.Int64,
|
||||||
|
Valid: bet.UserID.Valid,
|
||||||
|
},
|
||||||
|
IsShopBet: bet.IsShopBet,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newBet, err := s.queries.CreateBet(ctx, dbgen.CreateBetParams{
|
func convertCreateBet(bet domain.CreateBet) dbgen.CreateBetParams {
|
||||||
|
return dbgen.CreateBetParams{
|
||||||
Amount: int64(bet.Amount),
|
Amount: int64(bet.Amount),
|
||||||
TotalOdds: bet.TotalOdds,
|
TotalOdds: bet.TotalOdds,
|
||||||
Status: int32(bet.Status),
|
Status: int32(bet.Status),
|
||||||
|
|
@ -24,28 +43,17 @@ func (s *Store) CreateBet(ctx context.Context, bet domain.Bet) (domain.Bet, erro
|
||||||
Int64: bet.UserID.Value,
|
Int64: bet.UserID.Value,
|
||||||
Valid: bet.UserID.Valid,
|
Valid: bet.UserID.Valid,
|
||||||
},
|
},
|
||||||
})
|
IsShopBet: bet.IsShopBet,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) {
|
||||||
|
|
||||||
|
newBet, err := s.queries.CreateBet(ctx, convertCreateBet(bet))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Bet{}, err
|
return domain.Bet{}, err
|
||||||
}
|
}
|
||||||
|
return convertDBBet(newBet), err
|
||||||
return domain.Bet{
|
|
||||||
ID: newBet.ID,
|
|
||||||
Amount: domain.Currency(newBet.Amount),
|
|
||||||
TotalOdds: newBet.TotalOdds,
|
|
||||||
Status: domain.BetStatus(newBet.Status),
|
|
||||||
FullName: newBet.FullName,
|
|
||||||
PhoneNumber: newBet.PhoneNumber,
|
|
||||||
BranchID: domain.ValidInt64{
|
|
||||||
Value: newBet.BranchID.Int64,
|
|
||||||
Valid: newBet.BranchID.Valid,
|
|
||||||
},
|
|
||||||
UserID: domain.ValidInt64{
|
|
||||||
Value: newBet.UserID.Int64,
|
|
||||||
Valid: newBet.UserID.Valid,
|
|
||||||
},
|
|
||||||
}, err
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,22 +63,7 @@ func (s *Store) GetBetByID(ctx context.Context, id int64) (domain.Bet, error) {
|
||||||
return domain.Bet{}, err
|
return domain.Bet{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return domain.Bet{
|
return convertDBBet(bet), nil
|
||||||
ID: bet.ID,
|
|
||||||
Amount: domain.Currency(bet.Amount),
|
|
||||||
TotalOdds: bet.TotalOdds,
|
|
||||||
Status: domain.BetStatus(bet.Status),
|
|
||||||
FullName: bet.FullName,
|
|
||||||
PhoneNumber: bet.PhoneNumber,
|
|
||||||
BranchID: domain.ValidInt64{
|
|
||||||
Value: bet.BranchID.Int64,
|
|
||||||
Valid: bet.BranchID.Valid,
|
|
||||||
},
|
|
||||||
UserID: domain.ValidInt64{
|
|
||||||
Value: bet.UserID.Int64,
|
|
||||||
Valid: bet.UserID.Valid,
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetAllBets(ctx context.Context) ([]domain.Bet, error) {
|
func (s *Store) GetAllBets(ctx context.Context) ([]domain.Bet, error) {
|
||||||
|
|
@ -82,22 +75,7 @@ func (s *Store) GetAllBets(ctx context.Context) ([]domain.Bet, error) {
|
||||||
|
|
||||||
var result []domain.Bet
|
var result []domain.Bet
|
||||||
for _, bet := range bets {
|
for _, bet := range bets {
|
||||||
result = append(result, domain.Bet{
|
result = append(result, convertDBBet(bet))
|
||||||
ID: bet.ID,
|
|
||||||
Amount: domain.Currency(bet.Amount),
|
|
||||||
TotalOdds: bet.TotalOdds,
|
|
||||||
Status: domain.BetStatus(bet.Status),
|
|
||||||
FullName: bet.FullName,
|
|
||||||
PhoneNumber: bet.PhoneNumber,
|
|
||||||
BranchID: domain.ValidInt64{
|
|
||||||
Value: bet.BranchID.Int64,
|
|
||||||
Valid: bet.BranchID.Valid,
|
|
||||||
},
|
|
||||||
UserID: domain.ValidInt64{
|
|
||||||
Value: bet.UserID.Int64,
|
|
||||||
Valid: bet.UserID.Valid,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
|
|
||||||
|
|
@ -8,24 +8,30 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Store) CreateTicket(ctx context.Context, amount domain.Currency, totalOdds float32) (domain.Ticket, error) {
|
func convertDBTicket(ticket dbgen.Ticket) domain.Ticket {
|
||||||
|
return domain.Ticket{
|
||||||
|
ID: ticket.ID,
|
||||||
|
Amount: domain.Currency(ticket.Amount.Int64),
|
||||||
|
TotalOdds: ticket.TotalOdds,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ticket, err := s.queries.CreateTicket(ctx, dbgen.CreateTicketParams{
|
func convertCreateTicket(ticket domain.CreateTicket) dbgen.CreateTicketParams {
|
||||||
|
return dbgen.CreateTicketParams{
|
||||||
Amount: pgtype.Int8{
|
Amount: pgtype.Int8{
|
||||||
Int64: int64(amount),
|
Int64: int64(ticket.Amount),
|
||||||
},
|
},
|
||||||
TotalOdds: totalOdds,
|
TotalOdds: ticket.TotalOdds,
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) CreateTicket(ctx context.Context, ticket domain.CreateTicket) (domain.Ticket, error) {
|
||||||
|
|
||||||
|
newTicket, err := s.queries.CreateTicket(ctx, convertCreateTicket(ticket))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Ticket{}, err
|
return domain.Ticket{}, err
|
||||||
}
|
}
|
||||||
|
return convertDBTicket(newTicket), err
|
||||||
return domain.Ticket{
|
|
||||||
ID: ticket.ID,
|
|
||||||
Amount: amount,
|
|
||||||
TotalOdds: totalOdds,
|
|
||||||
}, err
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,11 +41,7 @@ func (s *Store) GetTicketByID(ctx context.Context, id int64) (domain.Ticket, err
|
||||||
return domain.Ticket{}, err
|
return domain.Ticket{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return domain.Ticket{
|
return convertDBTicket(ticket), nil
|
||||||
ID: ticket.ID,
|
|
||||||
Amount: domain.Currency(ticket.Amount.Int64),
|
|
||||||
TotalOdds: ticket.TotalOdds,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetAllTickets(ctx context.Context) ([]domain.Ticket, error) {
|
func (s *Store) GetAllTickets(ctx context.Context) ([]domain.Ticket, error) {
|
||||||
|
|
@ -51,11 +53,7 @@ func (s *Store) GetAllTickets(ctx context.Context) ([]domain.Ticket, error) {
|
||||||
|
|
||||||
var result []domain.Ticket
|
var result []domain.Ticket
|
||||||
for _, ticket := range tickets {
|
for _, ticket := range tickets {
|
||||||
result = append(result, domain.Ticket{
|
result = append(result, convertDBTicket(ticket))
|
||||||
ID: ticket.ID,
|
|
||||||
Amount: domain.Currency(ticket.Amount.Int64),
|
|
||||||
TotalOdds: ticket.TotalOdds,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ticket
|
package bet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type BetStore interface {
|
type BetStore interface {
|
||||||
CreateBet(ctx context.Context, bet domain.Bet) (domain.Bet, error)
|
CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error)
|
||||||
GetBetByID(ctx context.Context, id int64) (domain.Bet, error)
|
GetBetByID(ctx context.Context, id int64) (domain.Bet, error)
|
||||||
GetAllBets(ctx context.Context) ([]domain.Bet, error)
|
GetAllBets(ctx context.Context) ([]domain.Bet, error)
|
||||||
UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error
|
UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ticket
|
package bet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -16,7 +16,7 @@ func NewService(betStore BetStore) *Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) CreateBet(ctx context.Context, bet domain.Bet) (domain.Bet, error) {
|
func (s *Service) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) {
|
||||||
return s.betStore.CreateBet(ctx, bet)
|
return s.betStore.CreateBet(ctx, bet)
|
||||||
}
|
}
|
||||||
func (s *Service) GetBetByID(ctx context.Context, id int64) (domain.Bet, error) {
|
func (s *Service) GetBetByID(ctx context.Context, id int64) (domain.Bet, error) {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type TicketStore interface {
|
type TicketStore interface {
|
||||||
CreateTicket(ctx context.Context, amount domain.Currency, totalOdds float32) (domain.Ticket, error)
|
CreateTicket(ctx context.Context, ticket domain.CreateTicket) (domain.Ticket, error)
|
||||||
GetTicketByID(ctx context.Context, id int64) (domain.Ticket, error)
|
GetTicketByID(ctx context.Context, id int64) (domain.Ticket, error)
|
||||||
GetAllTickets(ctx context.Context) ([]domain.Ticket, error)
|
GetAllTickets(ctx context.Context) ([]domain.Ticket, error)
|
||||||
DeleteOldTickets(ctx context.Context) error
|
DeleteOldTickets(ctx context.Context) error
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ func NewService(ticketStore TicketStore) *Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) CreateTicket(ctx context.Context, amount domain.Currency, totalOdds float32) (domain.Ticket, error) {
|
func (s *Service) CreateTicket(ctx context.Context, ticket domain.CreateTicket) (domain.Ticket, error) {
|
||||||
return s.ticketStore.CreateTicket(ctx, amount, totalOdds)
|
return s.ticketStore.CreateTicket(ctx, ticket)
|
||||||
}
|
}
|
||||||
func (s *Service) GetTicketByID(ctx context.Context, id int64) (domain.Ticket, error) {
|
func (s *Service) GetTicketByID(ctx context.Context, id int64) (domain.Ticket, error) {
|
||||||
return s.ticketStore.GetTicketByID(ctx, id)
|
return s.ticketStore.GetTicketByID(ctx, id)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
|
||||||
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
|
||||||
jwtutil "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/jwt"
|
jwtutil "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/jwt"
|
||||||
customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator"
|
customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator"
|
||||||
|
|
@ -18,6 +20,8 @@ type App struct {
|
||||||
port int
|
port int
|
||||||
authSvc *authentication.Service
|
authSvc *authentication.Service
|
||||||
userSvc *user.Service
|
userSvc *user.Service
|
||||||
|
ticketSvc *ticket.Service
|
||||||
|
betSvc *bet.Service
|
||||||
validator *customvalidator.CustomValidator
|
validator *customvalidator.CustomValidator
|
||||||
JwtConfig jwtutil.JwtConfig
|
JwtConfig jwtutil.JwtConfig
|
||||||
}
|
}
|
||||||
|
|
@ -28,6 +32,8 @@ func NewApp(
|
||||||
logger *slog.Logger,
|
logger *slog.Logger,
|
||||||
JwtConfig jwtutil.JwtConfig,
|
JwtConfig jwtutil.JwtConfig,
|
||||||
userSvc *user.Service,
|
userSvc *user.Service,
|
||||||
|
ticketSvc *ticket.Service,
|
||||||
|
betSvc *bet.Service,
|
||||||
) *App {
|
) *App {
|
||||||
app := fiber.New(fiber.Config{
|
app := fiber.New(fiber.Config{
|
||||||
CaseSensitive: true,
|
CaseSensitive: true,
|
||||||
|
|
@ -43,6 +49,8 @@ func NewApp(
|
||||||
logger: logger,
|
logger: logger,
|
||||||
JwtConfig: JwtConfig,
|
JwtConfig: JwtConfig,
|
||||||
userSvc: userSvc,
|
userSvc: userSvc,
|
||||||
|
ticketSvc: ticketSvc,
|
||||||
|
betSvc: betSvc,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.initAppRoutes()
|
s.initAppRoutes()
|
||||||
|
|
|
||||||
266
internal/web_server/handlers/bet_handler.go
Normal file
266
internal/web_server/handlers/bet_handler.go
Normal file
|
|
@ -0,0 +1,266 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
||||||
|
customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateBetReq struct {
|
||||||
|
Outcomes []int64 `json:"outcomes"`
|
||||||
|
Amount float32 `json:"amount" example:"100.0"`
|
||||||
|
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
||||||
|
Status domain.BetStatus `json:"status" example:"1"`
|
||||||
|
FullName string `json:"full_name" example:"John"`
|
||||||
|
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
||||||
|
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BetRes struct {
|
||||||
|
ID int64 `json:"id" example:"1"`
|
||||||
|
Outcomes []domain.Outcome `json:"outcomes"`
|
||||||
|
Amount float32 `json:"amount" example:"100.0"`
|
||||||
|
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
||||||
|
Status domain.BetStatus `json:"status" example:"1"`
|
||||||
|
FullName string `json:"full_name" example:"John"`
|
||||||
|
PhoneNumber string `json:"phone_number" example:"1234567890"`
|
||||||
|
BranchID int64 `json:"branch_id" example:"2"`
|
||||||
|
UserID int64 `json:"user_id" example:"2"`
|
||||||
|
IsShopBet bool `json:"is_shop_bet" example:"false"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertBet(bet domain.Bet) BetRes {
|
||||||
|
return BetRes{
|
||||||
|
ID: bet.ID,
|
||||||
|
Outcomes: bet.Outcomes,
|
||||||
|
Amount: bet.Amount.Float64(),
|
||||||
|
TotalOdds: bet.TotalOdds,
|
||||||
|
Status: bet.Status,
|
||||||
|
FullName: bet.FullName,
|
||||||
|
PhoneNumber: bet.PhoneNumber,
|
||||||
|
BranchID: bet.BranchID.Value,
|
||||||
|
UserID: bet.UserID.Value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateBet godoc
|
||||||
|
// @Summary Create a bet
|
||||||
|
// @Description Creates a bet
|
||||||
|
// @Tags bet
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param createBet body CreateBetReq true "Creates bet"
|
||||||
|
// @Success 200 {object} BetRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /bet [post]
|
||||||
|
func CreateBet(logger *slog.Logger, betSvc *bet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
|
||||||
|
// TODO: Check the token, and find the role and get the branch id from there
|
||||||
|
|
||||||
|
// TODO Reduce amount from the branch wallet
|
||||||
|
|
||||||
|
var isShopBet bool = true
|
||||||
|
var branchID int64 = 1
|
||||||
|
var userID int64
|
||||||
|
|
||||||
|
var req CreateBetReq
|
||||||
|
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
logger.Error("CreateBetReq failed", "error", err)
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||||
|
"error": "Invalid request",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
valErrs, ok := validator.Validate(c, req)
|
||||||
|
if !ok {
|
||||||
|
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Validate Outcomes Here and make sure they didn't expire
|
||||||
|
|
||||||
|
bet, err := betSvc.CreateBet(c.Context(), domain.CreateBet{
|
||||||
|
Outcomes: req.Outcomes,
|
||||||
|
Amount: domain.Currency(req.Amount),
|
||||||
|
TotalOdds: req.TotalOdds,
|
||||||
|
Status: req.Status,
|
||||||
|
FullName: req.FullName,
|
||||||
|
PhoneNumber: req.PhoneNumber,
|
||||||
|
|
||||||
|
BranchID: domain.ValidInt64{
|
||||||
|
Value: branchID,
|
||||||
|
Valid: isShopBet,
|
||||||
|
},
|
||||||
|
UserID: domain.ValidInt64{
|
||||||
|
Value: userID,
|
||||||
|
Valid: !isShopBet,
|
||||||
|
},
|
||||||
|
IsShopBet: req.IsShopBet,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("CreateBetReq failed", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Internal Server Error", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := convertBet(bet)
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Bet Created", res, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllBet godoc
|
||||||
|
// @Summary Gets all bets
|
||||||
|
// @Description Gets all the bets
|
||||||
|
// @Tags bet
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} BetRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /bet [get]
|
||||||
|
func GetAllBet(logger *slog.Logger, betSvc *bet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
bets, err := betSvc.GetAllBets(c.Context())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to get bets", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve bets", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
var res []BetRes
|
||||||
|
for _, bet := range bets {
|
||||||
|
res = append(res, convertBet(bet))
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "All Bets Retrieved", res, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBetByID godoc
|
||||||
|
// @Summary Gets bet by id
|
||||||
|
// @Description Gets a single bet by id
|
||||||
|
// @Tags bet
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "Bet ID"
|
||||||
|
// @Success 200 {object} BetRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /bet/{id} [get]
|
||||||
|
func GetBetByID(logger *slog.Logger, betSvc *bet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
betID := c.Params("id")
|
||||||
|
id, err := strconv.ParseInt(betID, 10, 64)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Invalid bet ID", "betID", betID, "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid bet ID", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
bet, err := betSvc.GetBetByID(c.Context(), id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to get bet by ID", "betID", id, "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve bet", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := convertBet(bet)
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Bet retrieved successfully", res, nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateCashOutReq struct {
|
||||||
|
CashedOut bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateCashOut godoc
|
||||||
|
// @Summary Updates the cashed out field
|
||||||
|
// @Description Updates the cashed out field
|
||||||
|
// @Tags bet
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "Bet ID"
|
||||||
|
// @Param updateCashOut body UpdateCashOutReq true "Updates Cashed Out"
|
||||||
|
// @Success 200 {object} response.APIResponse
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /bet/{id} [patch]
|
||||||
|
func UpdateCashOut(logger *slog.Logger, betSvc *bet.Service,
|
||||||
|
validator *customvalidator.CustomValidator) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
betID := c.Params("id")
|
||||||
|
id, err := strconv.ParseInt(betID, 10, 64)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Invalid bet ID", "betID", betID, "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid bet ID", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
var req UpdateCashOutReq
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
logger.Error("UpdateCashOutReq failed", "error", err)
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||||
|
"error": "Invalid request",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
valErrs, ok := validator.Validate(c, req)
|
||||||
|
if !ok {
|
||||||
|
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = betSvc.UpdateCashOut(c.Context(), id, req.CashedOut)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to update cash out bet", "betID", id, "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update cash out bet", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Bet updated successfully", nil, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteBet godoc
|
||||||
|
// @Summary Deletes bet by id
|
||||||
|
// @Description Deletes bet by id
|
||||||
|
// @Tags bet
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "Bet ID"
|
||||||
|
// @Success 200 {object} response.APIResponse
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /bet/{id} [delete]
|
||||||
|
func DeleteBet(logger *slog.Logger, betSvc *bet.Service,
|
||||||
|
validator *customvalidator.CustomValidator) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
betID := c.Params("id")
|
||||||
|
id, err := strconv.ParseInt(betID, 10, 64)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Invalid bet ID", "betID", betID, "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid bet ID", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = betSvc.DeleteBet(c.Context(), id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to delete by ID", "betID", id, "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to delete bet", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Bet removed successfully", nil, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
153
internal/web_server/handlers/ticket_handler.go
Normal file
153
internal/web_server/handlers/ticket_handler.go
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
|
||||||
|
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
|
||||||
|
customvalidator "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/validator"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateTicketReq struct {
|
||||||
|
Outcomes []int64 `json:"outcomes"`
|
||||||
|
Amount float32 `json:"amount" example:"100.0"`
|
||||||
|
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
||||||
|
}
|
||||||
|
type CreateTicketRes struct {
|
||||||
|
FastCode int64 `json:"fast_code" example:"1234"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateTicket godoc
|
||||||
|
// @Summary Create a temporary ticket
|
||||||
|
// @Description Creates a temporary ticket
|
||||||
|
// @Tags ticket
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param createTicket body CreateTicketReq true "Creates ticket"
|
||||||
|
// @Success 200 {object} CreateTicketRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /ticket [post]
|
||||||
|
func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service,
|
||||||
|
validator *customvalidator.CustomValidator) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
var req CreateTicketReq
|
||||||
|
if err := c.BodyParser(&req); err != nil {
|
||||||
|
logger.Error("CreateTicketReq failed", "error", err)
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||||
|
"error": "Invalid request",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
valErrs, ok := validator.Validate(c, req)
|
||||||
|
if !ok {
|
||||||
|
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Validate Outcomes Here and make sure they didn't expire
|
||||||
|
|
||||||
|
ticket, err := ticketSvc.CreateTicket(c.Context(), domain.CreateTicket{
|
||||||
|
Outcomes: req.Outcomes,
|
||||||
|
Amount: domain.Currency(req.Amount),
|
||||||
|
TotalOdds: req.TotalOdds,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("CreateTicketReq failed", "error", err)
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||||
|
"error": "Internal server error",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
res := CreateTicketRes{
|
||||||
|
FastCode: ticket.ID,
|
||||||
|
}
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Ticket Created", res, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TicketRes struct {
|
||||||
|
ID int64 `json:"id" example:"1"`
|
||||||
|
Outcomes []domain.Outcome `json:"outcomes"`
|
||||||
|
Amount float32 `json:"amount" example:"100.0"`
|
||||||
|
TotalOdds float32 `json:"total_odds" example:"4.22"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTicketByID godoc
|
||||||
|
// @Summary Get ticket by ID
|
||||||
|
// @Description Retrieve ticket details by ticket ID
|
||||||
|
// @Tags ticket
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "Ticket ID"
|
||||||
|
// @Success 200 {object} TicketRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /ticket/{id} [get]
|
||||||
|
func GetTicketByID(logger *slog.Logger, ticketSvc *ticket.Service,
|
||||||
|
validator *customvalidator.CustomValidator) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
ticketID := c.Params("id")
|
||||||
|
|
||||||
|
id, err := strconv.ParseInt(ticketID, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Invalid ticket ID", "ticketID", ticketID, "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid ticket ID", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
ticket, err := ticketSvc.GetTicketByID(c.Context(), id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to get ticket by ID", "ticketID", id, "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve ticket", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := TicketRes{
|
||||||
|
ID: ticket.ID,
|
||||||
|
Outcomes: ticket.Outcomes,
|
||||||
|
Amount: ticket.Amount.Float64(),
|
||||||
|
TotalOdds: ticket.TotalOdds,
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "Ticket retrieved successfully", res, nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllTickets godoc
|
||||||
|
// @Summary Get all tickets
|
||||||
|
// @Description Retrieve all tickets
|
||||||
|
// @Tags ticket
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} TicketRes
|
||||||
|
// @Failure 400 {object} response.APIResponse
|
||||||
|
// @Failure 500 {object} response.APIResponse
|
||||||
|
// @Router /ticket [get]
|
||||||
|
func GetAllTickets(logger *slog.Logger, ticketSvc *ticket.Service,
|
||||||
|
validator *customvalidator.CustomValidator) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
tickets, err := ticketSvc.GetAllTickets(c.Context())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to get tickets", "error", err)
|
||||||
|
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve tickets", err, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
var res []TicketRes
|
||||||
|
|
||||||
|
for _, ticket := range tickets {
|
||||||
|
res = append(res, TicketRes{
|
||||||
|
ID: ticket.ID,
|
||||||
|
Outcomes: ticket.Outcomes,
|
||||||
|
Amount: ticket.Amount.Float64(),
|
||||||
|
TotalOdds: ticket.TotalOdds,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.WriteJSON(c, fiber.StatusOK, "All Tickets retrieved", res, nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,7 +27,20 @@ func (a *App) initAppRoutes() {
|
||||||
a.fiber.Post("/user/checkPhoneEmailExist", handlers.CheckPhoneEmailExist(a.logger, a.userSvc, a.validator))
|
a.fiber.Post("/user/checkPhoneEmailExist", handlers.CheckPhoneEmailExist(a.logger, a.userSvc, a.validator))
|
||||||
a.fiber.Get("/user/profile", a.authMiddleware, handlers.UserProfile(a.logger, a.userSvc))
|
a.fiber.Get("/user/profile", a.authMiddleware, handlers.UserProfile(a.logger, a.userSvc))
|
||||||
// Swagger
|
// Swagger
|
||||||
a.fiber.Get("/swagger/*", fiberSwagger.WrapHandler)
|
a.fiber.Get("/swagger/*", fiberSwagger.FiberWrapHandler())
|
||||||
|
|
||||||
|
// Ticket
|
||||||
|
a.fiber.Post("/ticket", handlers.CreateTicket(a.logger, a.ticketSvc, a.validator))
|
||||||
|
a.fiber.Get("/ticket", handlers.GetAllTickets(a.logger, a.ticketSvc, a.validator))
|
||||||
|
a.fiber.Get("/ticket/:id", handlers.GetTicketByID(a.logger, a.ticketSvc, a.validator))
|
||||||
|
|
||||||
|
// Bet
|
||||||
|
a.fiber.Post("/bet", handlers.CreateBet(a.logger, a.betSvc, a.validator))
|
||||||
|
a.fiber.Get("/bet", handlers.GetAllBet(a.logger, a.betSvc, a.validator))
|
||||||
|
a.fiber.Get("/bet/:id", handlers.GetAllBet(a.logger, a.betSvc, a.validator))
|
||||||
|
a.fiber.Patch("/bet/:id", handlers.UpdateCashOut(a.logger, a.betSvc, a.validator))
|
||||||
|
a.fiber.Delete("/bet/:id", handlers.DeleteBet(a.logger, a.betSvc, a.validator))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///user/profile get
|
///user/profile get
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user