company management

This commit is contained in:
Samuel Tariku 2025-04-23 03:44:17 +03:00
parent 991199c3dc
commit 8c536a6d2f
45 changed files with 1681 additions and 362 deletions

View File

@ -16,11 +16,12 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notfication"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/transaction"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/user"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
httpserver "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server"
@ -67,22 +68,23 @@ func main() {
eventSvc := event.New(cfg.Bet365Token, store)
oddsSvc := odds.New(cfg.Bet365Token, store)
ticketSvc := ticket.NewService(store)
betSvc := bet.NewService(store)
walletSvc := wallet.NewService(store, store)
transactionSvc := transaction.NewService(store)
branchSvc := branch.NewService(store)
companySvc := company.NewService(store)
notificationRepo := repository.NewNotificationRepository(store)
notificationSvc := notificationservice.New(notificationRepo, logger, cfg)
httpserver.StartDataFetchingCrons(eventSvc, oddsSvc)
app := httpserver.NewApp(cfg.Port, v, authSvc, logger, jwtutil.JwtConfig{
JwtAccessKey: cfg.JwtKey,
JwtAccessExpiry: cfg.AccessExpiry,
}, userSvc, ticketSvc, betSvc, walletSvc, transactionSvc, branchSvc, notificationSvc, oddsSvc, eventSvc)
}, userSvc,
ticketSvc, betSvc, walletSvc, transactionSvc, branchSvc, companySvc, notificationSvc, oddsSvc, eventSvc)
logger.Info("Starting server", "port", cfg.Port)

View File

@ -1,22 +1,18 @@
-- Drop tables that depend on service_type_setting
DROP TABLE IF EXISTS service_type_setting;
-- Drop product-related tables and types
DROP TABLE IF EXISTS product;
DROP TYPE IF EXISTS tier_group;
-- Drop onboarding-related tables and types
DROP TABLE IF EXISTS verification_key;
DROP TABLE IF EXISTS onboarding_user;
DROP TYPE IF EXISTS verification_status;
DROP TYPE IF EXISTS onboarding_status;
-- Drop staff-related tables and types
DROP TABLE IF EXISTS staff_session;
DROP TABLE IF EXISTS user_agent;
DROP TABLE IF EXISTS staff;
DROP TYPE IF EXISTS password_status;
-- Drop mobile app-related tables and types
DROP TABLE IF EXISTS user_devices;
DROP TABLE IF EXISTS user_session;
@ -25,17 +21,14 @@ DROP TABLE IF EXISTS users;
DROP TYPE IF EXISTS device_type;
DROP TYPE IF EXISTS registeration_type;
DROP TYPE IF EXISTS customer_group;
-- Drop linked accounts and beneficiary tables and types
DROP TABLE IF EXISTS beneficiary;
DROP TYPE IF EXISTS fund_destination;
-- Drop maker checker-related tables and types
DROP TABLE IF EXISTS workflow;
DROP TYPE IF EXISTS approval_status;
DROP TYPE IF EXISTS action_type;
DROP TYPE IF EXISTS context_type;
-- Drop authorization-related tables and types
DROP TRIGGER IF EXISTS enforce_unique_array ON policy;
DROP FUNCTION IF EXISTS check_unique_array;
@ -43,11 +36,9 @@ DROP TABLE IF EXISTS policy;
DROP TABLE IF EXISTS roles;
DROP TYPE IF EXISTS policy_action;
DROP TYPE IF EXISTS policy_object;
-- Drop bank-related tables and types
DROP TABLE IF EXISTS bank;
DROP TABLE IF EXISTS flagged_users;
-- Drop transaction-related tables and types
DROP TABLE IF EXISTS transaction_daily;
DROP TABLE IF EXISTS system_limits;
@ -57,22 +48,18 @@ DROP TYPE IF EXISTS service_type;
DROP TYPE IF EXISTS channel;
DROP TYPE IF EXISTS transaction_category;
DROP TYPE IF EXISTS registration_type;
-- Drop branches and related tables
DROP TABLE IF EXISTS branches;
DROP TABLE IF EXISTS cities;
DROP TABLE IF EXISTS districts;
DROP TABLE IF EXISTS regions;
-- Drop activity logs
DROP TABLE IF EXISTS activity;
-- Drop ussd account and related enums
DROP TABLE IF EXISTS ussd_account;
DROP TYPE IF EXISTS ua_pin_status;
DROP TYPE IF EXISTS ua_status;
DROP TYPE IF EXISTS ua_registaration_type;
-- Drop FortuneBet
DROP TABLE IF EXISTS tickets;
DROP TABLE IF EXISTS ticket_outcomes;
@ -83,13 +70,9 @@ DROP TABLE IF EXISTS customer_wallets;
DROP TABLE IF EXISTS wallet_transfer;
DROP TABLE IF EXISTS transactions;
DROP TABLE IF EXISTS branches;
DROP TABLE IF EXISTS companies;
DROP TABLE IF EXISTS supported_operations;
DROP TABLE IF EXISTS refresh_tokens;
DROP TABLE IF EXISTS otps;
DROP TABLE IF EXISTS odds;
DROP TABLE IF EXISTS events;
DROP TABLE IF EXISTS events;

View File

@ -78,6 +78,7 @@ CREATE TABLE IF NOT EXISTS bet_outcomes (
odd_name VARCHAR(255) NOT NULL,
odd_header VARCHAR(255) NOT NULL,
odd_handicap VARCHAR(255) NOT NULL,
status INT NOT NULL DEFAULT 0,
expires TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS ticket_outcomes (
@ -93,6 +94,7 @@ CREATE TABLE IF NOT EXISTS ticket_outcomes (
odd_name VARCHAR(255) NOT NULL,
odd_header VARCHAR(255) NOT NULL,
odd_handicap VARCHAR(255) NOT NULL,
status INT NOT NULL DEFAULT 0,
expires TIMESTAMP NOT NULL
);
CREATE VIEW bet_with_outcomes AS
@ -238,6 +240,12 @@ CREATE TABLE odds (
UNIQUE (event_id, market_id, name, handicap),
UNIQUE (event_id, market_id)
);
CREATE TABLE companies (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
admin_id BIGINT NOT NULL,
wallet_id BIGINT NOT NULL
);
ALTER TABLE refresh_tokens
ADD CONSTRAINT fk_refresh_tokens_users FOREIGN KEY (user_id) REFERENCES users(id);
ALTER TABLE bets

View File

@ -27,7 +27,20 @@ INSERT INTO bet_outcomes (
odd_handicap,
expires
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);
VALUES (
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8,
$9,
$10,
$11,
$12
);
-- name: GetAllBets :many
SELECT *
FROM bet_with_outcomes;
@ -48,6 +61,10 @@ UPDATE bets
SET cashed_out = $2,
updated_at = CURRENT_TIMESTAMP
WHERE id = $1;
-- name: UpdateBetOutcomeStatus :exec
UPDATE bet_outcomes
SET status = $1
WHERE id = $2;
-- name: UpdateStatus :exec
UPDATE bets
SET status = $2,

24
db/query/company.sql Normal file
View File

@ -0,0 +1,24 @@
-- name: CreateCompany :one
INSERT INTO companies (
name,
admin_id,
wallet_id
)
VALUES ($1, $2, $3)
RETURNING *;
-- name: GetAllCompanies :many
SELECT *
FROM companies;
-- name: GetCompanyByID :one
SELECT *
FROM companies
WHERE id = $1;
-- name: UpdateCompany :one
UPDATE companies
SET name = $1,
admin_id = $2
WHERE id = $3
RETURNING *;
-- name: DeleteCompany :exec
DELETE FROM companies
WHERE id = $1;

View File

@ -144,7 +144,15 @@ ORDER BY start_time ASC;
SELECT COUNT(*)
FROM events
WHERE is_live = false
AND status = 'upcoming';
AND status = 'upcoming'
AND (
league_id = $1
OR $1 IS NULL
)
AND (
sport_id = $2
OR $2 IS NULL
);
-- name: GetPaginatedUpcomingEvents :many
SELECT id,
sport_id,
@ -165,6 +173,14 @@ SELECT id,
FROM events
WHERE is_live = false
AND status = 'upcoming'
AND (
league_id = $3
OR $3 IS NULL
)
AND (
sport_id = $4
OR $4 IS NULL
)
ORDER BY start_time ASC
LIMIT $1 OFFSET $2;
-- name: GetUpcomingByID :one

View File

@ -42,6 +42,10 @@ WHERE id = $1;
SELECT *
FROM ticket_outcomes
WHERE ticket_id = $1;
-- name: UpdateTicketOutcomeStatus :exec
UPDATE ticket_outcomes
SET status = $1
WHERE id = $2;
-- name: DeleteTicket :exec
DELETE FROM tickets
WHERE id = $1;

View File

@ -993,6 +993,225 @@ const docTemplate = `{
}
}
},
"/company": {
"get": {
"description": "Gets all companies",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Gets all companies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.CompanyRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"post": {
"description": "Creates a company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Create a company",
"parameters": [
{
"description": "Creates company",
"name": "createCompany",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateCompanyReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/company/{id}": {
"get": {
"description": "Gets a single company by id",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Gets company by id",
"parameters": [
{
"type": "integer",
"description": "Company ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"put": {
"description": "Updates a company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Updates a company",
"parameters": [
{
"type": "integer",
"description": "Company ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update Company",
"name": "updateCompany",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateCompanyReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"delete": {
"description": "Delete the company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Delete the company",
"parameters": [
{
"type": "integer",
"description": "Company 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"
}
}
}
}
},
"/company/{id}/branch": {
"get": {
"description": "Gets branches by company id",
@ -1315,6 +1534,18 @@ const docTemplate = `{
"description": "Page size",
"name": "page_size",
"in": "query"
},
{
"type": "string",
"description": "League ID Filter",
"name": "league_id",
"in": "query"
},
{
"type": "string",
"description": "Sport ID Filter",
"name": "sport_id",
"in": "query"
}
],
"responses": {
@ -2696,24 +2927,17 @@ const docTemplate = `{
"odd_name": {
"type": "string",
"example": "1"
},
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
}
}
},
"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.Odd": {
"type": "object",
"properties": {
@ -2765,6 +2989,21 @@ const docTemplate = `{
}
}
},
"domain.OutcomeStatus": {
"type": "integer",
"enum": [
0,
1,
2,
3
],
"x-enum-varnames": [
"OUTCOME_STATUS_PENDING",
"OUTCOME_STATUS_WIN",
"OUTCOME_STATUS_LOSS",
"OUTCOME_STATUS_ERROR"
]
},
"domain.PaymentOption": {
"type": "integer",
"enum": [
@ -2869,6 +3108,14 @@ const docTemplate = `{
"type": "string",
"example": "1"
},
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
},
"ticket_id": {
"type": "integer",
"example": 1
@ -2976,7 +3223,7 @@ const docTemplate = `{
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.BetStatus"
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
@ -3102,6 +3349,27 @@ const docTemplate = `{
}
}
},
"handlers.CompanyRes": {
"type": "object",
"properties": {
"admin_id": {
"type": "integer",
"example": 1
},
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "CompanyName"
},
"wallet_id": {
"type": "integer",
"example": 1
}
}
},
"handlers.CreateBetOutcomeReq": {
"type": "object",
"properties": {
@ -3148,7 +3416,7 @@ const docTemplate = `{
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.BetStatus"
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
@ -3232,6 +3500,19 @@ const docTemplate = `{
}
}
},
"handlers.CreateCompanyReq": {
"type": "object",
"properties": {
"admin_id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "CompanyName"
}
}
},
"handlers.CreateManagerReq": {
"type": "object",
"properties": {

View File

@ -985,6 +985,225 @@
}
}
},
"/company": {
"get": {
"description": "Gets all companies",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Gets all companies",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.CompanyRes"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"post": {
"description": "Creates a company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Create a company",
"parameters": [
{
"description": "Creates company",
"name": "createCompany",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateCompanyReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/company/{id}": {
"get": {
"description": "Gets a single company by id",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Gets company by id",
"parameters": [
{
"type": "integer",
"description": "Company ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"put": {
"description": "Updates a company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Updates a company",
"parameters": [
{
"type": "integer",
"description": "Company ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update Company",
"name": "updateCompany",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateCompanyReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CompanyRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"delete": {
"description": "Delete the company",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"company"
],
"summary": "Delete the company",
"parameters": [
{
"type": "integer",
"description": "Company 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"
}
}
}
}
},
"/company/{id}/branch": {
"get": {
"description": "Gets branches by company id",
@ -1307,6 +1526,18 @@
"description": "Page size",
"name": "page_size",
"in": "query"
},
{
"type": "string",
"description": "League ID Filter",
"name": "league_id",
"in": "query"
},
{
"type": "string",
"description": "Sport ID Filter",
"name": "sport_id",
"in": "query"
}
],
"responses": {
@ -2688,24 +2919,17 @@
"odd_name": {
"type": "string",
"example": "1"
},
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
}
}
},
"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.Odd": {
"type": "object",
"properties": {
@ -2757,6 +2981,21 @@
}
}
},
"domain.OutcomeStatus": {
"type": "integer",
"enum": [
0,
1,
2,
3
],
"x-enum-varnames": [
"OUTCOME_STATUS_PENDING",
"OUTCOME_STATUS_WIN",
"OUTCOME_STATUS_LOSS",
"OUTCOME_STATUS_ERROR"
]
},
"domain.PaymentOption": {
"type": "integer",
"enum": [
@ -2861,6 +3100,14 @@
"type": "string",
"example": "1"
},
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
},
"ticket_id": {
"type": "integer",
"example": 1
@ -2968,7 +3215,7 @@
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.BetStatus"
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
@ -3094,6 +3341,27 @@
}
}
},
"handlers.CompanyRes": {
"type": "object",
"properties": {
"admin_id": {
"type": "integer",
"example": 1
},
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "CompanyName"
},
"wallet_id": {
"type": "integer",
"example": 1
}
}
},
"handlers.CreateBetOutcomeReq": {
"type": "object",
"properties": {
@ -3140,7 +3408,7 @@
"status": {
"allOf": [
{
"$ref": "#/definitions/domain.BetStatus"
"$ref": "#/definitions/domain.OutcomeStatus"
}
],
"example": 1
@ -3224,6 +3492,19 @@
}
}
},
"handlers.CreateCompanyReq": {
"type": "object",
"properties": {
"admin_id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "CompanyName"
}
}
},
"handlers.CreateManagerReq": {
"type": "object",
"properties": {

View File

@ -40,19 +40,11 @@ definitions:
odd_name:
example: "1"
type: string
status:
allOf:
- $ref: '#/definitions/domain.OutcomeStatus'
example: 1
type: object
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.Odd:
properties:
category:
@ -87,6 +79,18 @@ definitions:
source:
type: string
type: object
domain.OutcomeStatus:
enum:
- 0
- 1
- 2
- 3
type: integer
x-enum-varnames:
- OUTCOME_STATUS_PENDING
- OUTCOME_STATUS_WIN
- OUTCOME_STATUS_LOSS
- OUTCOME_STATUS_ERROR
domain.PaymentOption:
enum:
- 0
@ -165,6 +169,10 @@ definitions:
odd_name:
example: "1"
type: string
status:
allOf:
- $ref: '#/definitions/domain.OutcomeStatus'
example: 1
ticket_id:
example: 1
type: integer
@ -243,7 +251,7 @@ definitions:
type: string
status:
allOf:
- $ref: '#/definitions/domain.BetStatus'
- $ref: '#/definitions/domain.OutcomeStatus'
example: 1
total_odds:
example: 4.22
@ -331,6 +339,21 @@ definitions:
phone_number_exist:
type: boolean
type: object
handlers.CompanyRes:
properties:
admin_id:
example: 1
type: integer
id:
example: 1
type: integer
name:
example: CompanyName
type: string
wallet_id:
example: 1
type: integer
type: object
handlers.CreateBetOutcomeReq:
properties:
event_id:
@ -364,7 +387,7 @@ definitions:
type: string
status:
allOf:
- $ref: '#/definitions/domain.BetStatus'
- $ref: '#/definitions/domain.OutcomeStatus'
example: 1
total_odds:
example: 4.22
@ -422,6 +445,15 @@ definitions:
example: "1234567890"
type: string
type: object
handlers.CreateCompanyReq:
properties:
admin_id:
example: 1
type: integer
name:
example: CompanyName
type: string
type: object
handlers.CreateManagerReq:
properties:
email:
@ -1512,6 +1544,151 @@ paths:
summary: Update cashier
tags:
- cashier
/company:
get:
consumes:
- application/json
description: Gets all companies
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/handlers.CompanyRes'
type: array
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Gets all companies
tags:
- company
post:
consumes:
- application/json
description: Creates a company
parameters:
- description: Creates company
in: body
name: createCompany
required: true
schema:
$ref: '#/definitions/handlers.CreateCompanyReq'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handlers.CompanyRes'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Create a company
tags:
- company
/company/{id}:
delete:
consumes:
- application/json
description: Delete the company
parameters:
- description: Company 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: Delete the company
tags:
- company
get:
consumes:
- application/json
description: Gets a single company by id
parameters:
- description: Company ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handlers.CompanyRes'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Gets company by id
tags:
- company
put:
consumes:
- application/json
description: Updates a company
parameters:
- description: Company ID
in: path
name: id
required: true
type: integer
- description: Update Company
in: body
name: updateCompany
required: true
schema:
$ref: '#/definitions/handlers.CreateCompanyReq'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handlers.CompanyRes'
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.APIResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Updates a company
tags:
- company
/company/{id}/branch:
get:
consumes:
@ -1721,6 +1898,14 @@ paths:
in: query
name: page_size
type: integer
- description: League ID Filter
in: query
name: league_id
type: string
- description: Sport ID Filter
in: query
name: sport_id
type: string
produces:
- application/json
responses:

View File

@ -242,6 +242,22 @@ func (q *Queries) GetBetByID(ctx context.Context, id int64) (BetWithOutcome, err
return i, err
}
const UpdateBetOutcomeStatus = `-- name: UpdateBetOutcomeStatus :exec
UPDATE bet_outcomes
SET status = $1
WHERE id = $2
`
type UpdateBetOutcomeStatusParams struct {
Status int32 `json:"status"`
ID int64 `json:"id"`
}
func (q *Queries) UpdateBetOutcomeStatus(ctx context.Context, arg UpdateBetOutcomeStatusParams) error {
_, err := q.db.Exec(ctx, UpdateBetOutcomeStatus, arg.Status, arg.ID)
return err
}
const UpdateCashOut = `-- name: UpdateCashOut :exec
UPDATE bets
SET cashed_out = $2,

122
gen/db/company.sql.go Normal file
View File

@ -0,0 +1,122 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.28.0
// source: company.sql
package dbgen
import (
"context"
)
const CreateCompany = `-- name: CreateCompany :one
INSERT INTO companies (
name,
admin_id,
wallet_id
)
VALUES ($1, $2, $3)
RETURNING id, name, admin_id, wallet_id
`
type CreateCompanyParams struct {
Name string `json:"name"`
AdminID int64 `json:"admin_id"`
WalletID int64 `json:"wallet_id"`
}
func (q *Queries) CreateCompany(ctx context.Context, arg CreateCompanyParams) (Company, error) {
row := q.db.QueryRow(ctx, CreateCompany, arg.Name, arg.AdminID, arg.WalletID)
var i Company
err := row.Scan(
&i.ID,
&i.Name,
&i.AdminID,
&i.WalletID,
)
return i, err
}
const DeleteCompany = `-- name: DeleteCompany :exec
DELETE FROM companies
WHERE id = $1
`
func (q *Queries) DeleteCompany(ctx context.Context, id int64) error {
_, err := q.db.Exec(ctx, DeleteCompany, id)
return err
}
const GetAllCompanies = `-- name: GetAllCompanies :many
SELECT id, name, admin_id, wallet_id
FROM companies
`
func (q *Queries) GetAllCompanies(ctx context.Context) ([]Company, error) {
rows, err := q.db.Query(ctx, GetAllCompanies)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Company
for rows.Next() {
var i Company
if err := rows.Scan(
&i.ID,
&i.Name,
&i.AdminID,
&i.WalletID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const GetCompanyByID = `-- name: GetCompanyByID :one
SELECT id, name, admin_id, wallet_id
FROM companies
WHERE id = $1
`
func (q *Queries) GetCompanyByID(ctx context.Context, id int64) (Company, error) {
row := q.db.QueryRow(ctx, GetCompanyByID, id)
var i Company
err := row.Scan(
&i.ID,
&i.Name,
&i.AdminID,
&i.WalletID,
)
return i, err
}
const UpdateCompany = `-- name: UpdateCompany :one
UPDATE companies
SET name = $1,
admin_id = $2
WHERE id = $3
RETURNING id, name, admin_id, wallet_id
`
type UpdateCompanyParams struct {
Name string `json:"name"`
AdminID int64 `json:"admin_id"`
ID int64 `json:"id"`
}
func (q *Queries) UpdateCompany(ctx context.Context, arg UpdateCompanyParams) (Company, error) {
row := q.db.QueryRow(ctx, UpdateCompany, arg.Name, arg.AdminID, arg.ID)
var i Company
err := row.Scan(
&i.ID,
&i.Name,
&i.AdminID,
&i.WalletID,
)
return i, err
}

View File

@ -110,13 +110,23 @@ SELECT id,
FROM events
WHERE is_live = false
AND status = 'upcoming'
AND (
league_id = $3
OR $3 IS NULL
)
AND (
sport_id = $4
OR $4 IS NULL
)
ORDER BY start_time ASC
LIMIT $1 OFFSET $2
`
type GetPaginatedUpcomingEventsParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
LeagueID pgtype.Text `json:"league_id"`
SportID pgtype.Text `json:"sport_id"`
}
type GetPaginatedUpcomingEventsRow struct {
@ -139,7 +149,12 @@ type GetPaginatedUpcomingEventsRow struct {
}
func (q *Queries) GetPaginatedUpcomingEvents(ctx context.Context, arg GetPaginatedUpcomingEventsParams) ([]GetPaginatedUpcomingEventsRow, error) {
rows, err := q.db.Query(ctx, GetPaginatedUpcomingEvents, arg.Limit, arg.Offset)
rows, err := q.db.Query(ctx, GetPaginatedUpcomingEvents,
arg.Limit,
arg.Offset,
arg.LeagueID,
arg.SportID,
)
if err != nil {
return nil, err
}
@ -180,10 +195,23 @@ SELECT COUNT(*)
FROM events
WHERE is_live = false
AND status = 'upcoming'
AND (
league_id = $1
OR $1 IS NULL
)
AND (
sport_id = $2
OR $2 IS NULL
)
`
func (q *Queries) GetTotalEvents(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, GetTotalEvents)
type GetTotalEventsParams struct {
LeagueID pgtype.Text `json:"league_id"`
SportID pgtype.Text `json:"sport_id"`
}
func (q *Queries) GetTotalEvents(ctx context.Context, arg GetTotalEventsParams) (int64, error) {
row := q.db.QueryRow(ctx, GetTotalEvents, arg.LeagueID, arg.SportID)
var count int64
err := row.Scan(&count)
return count, err

View File

@ -37,6 +37,7 @@ type BetOutcome struct {
OddName string `json:"odd_name"`
OddHeader string `json:"odd_header"`
OddHandicap string `json:"odd_handicap"`
Status int32 `json:"status"`
Expires pgtype.Timestamp `json:"expires"`
}
@ -97,6 +98,13 @@ type BranchOperation struct {
UpdatedAt pgtype.Timestamp `json:"updated_at"`
}
type Company struct {
ID int64 `json:"id"`
Name string `json:"name"`
AdminID int64 `json:"admin_id"`
WalletID int64 `json:"wallet_id"`
}
type CustomerWallet struct {
ID int64 `json:"id"`
CustomerID int64 `json:"customer_id"`
@ -215,6 +223,7 @@ type TicketOutcome struct {
OddName string `json:"odd_name"`
OddHeader string `json:"odd_header"`
OddHandicap string `json:"odd_handicap"`
Status int32 `json:"status"`
Expires pgtype.Timestamp `json:"expires"`
}

View File

@ -133,7 +133,7 @@ func (q *Queries) GetTicketByID(ctx context.Context, id int64) (TicketWithOutcom
}
const GetTicketOutcome = `-- name: GetTicketOutcome :many
SELECT id, ticket_id, event_id, odd_id, home_team_name, away_team_name, market_id, market_name, odd, odd_name, odd_header, odd_handicap, expires
SELECT id, ticket_id, event_id, odd_id, home_team_name, away_team_name, market_id, market_name, odd, odd_name, odd_header, odd_handicap, status, expires
FROM ticket_outcomes
WHERE ticket_id = $1
`
@ -160,6 +160,7 @@ func (q *Queries) GetTicketOutcome(ctx context.Context, ticketID int64) ([]Ticke
&i.OddName,
&i.OddHeader,
&i.OddHandicap,
&i.Status,
&i.Expires,
); err != nil {
return nil, err
@ -171,3 +172,19 @@ func (q *Queries) GetTicketOutcome(ctx context.Context, ticketID int64) ([]Ticke
}
return items, nil
}
const UpdateTicketOutcomeStatus = `-- name: UpdateTicketOutcomeStatus :exec
UPDATE ticket_outcomes
SET status = $1
WHERE id = $2
`
type UpdateTicketOutcomeStatusParams struct {
Status int32 `json:"status"`
ID int64 `json:"id"`
}
func (q *Queries) UpdateTicketOutcomeStatus(ctx context.Context, arg UpdateTicketOutcomeStatusParams) error {
_, err := q.db.Exec(ctx, UpdateTicketOutcomeStatus, arg.Status, arg.ID)
return err
}

View File

@ -1,22 +1,24 @@
package domain
import "time"
import (
"time"
)
type BetOutcome struct {
ID int64 `json:"id" example:"1"`
BetID int64 `json:"bet_id" example:"1"`
EventID int64 `json:"event_id" example:"1"`
OddID int64 `json:"odd_id" example:"1"`
HomeTeamName string `json:"home_team_name" example:"Manchester"`
AwayTeamName string `json:"away_team_name" example:"Liverpool"`
MarketID int64 `json:"market_id" example:"1"`
MarketName string `json:"market_name" example:"Fulltime Result"`
Odd float32 `json:"odd" example:"1.5"`
OddName string `json:"odd_name" example:"1"`
OddHeader string `json:"odd_header" example:"1"`
OddHandicap string `json:"odd_handicap" example:"1"`
Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"`
ID int64 `json:"id" example:"1"`
BetID int64 `json:"bet_id" example:"1"`
EventID int64 `json:"event_id" example:"1"`
OddID int64 `json:"odd_id" example:"1"`
HomeTeamName string `json:"home_team_name" example:"Manchester"`
AwayTeamName string `json:"away_team_name" example:"Liverpool"`
MarketID int64 `json:"market_id" example:"1"`
MarketName string `json:"market_name" example:"Fulltime Result"`
Odd float32 `json:"odd" example:"1.5"`
OddName string `json:"odd_name" example:"1"`
OddHeader string `json:"odd_header" example:"1"`
OddHandicap string `json:"odd_handicap" example:"1"`
Status OutcomeStatus `json:"status" example:"1"`
Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"`
}
type CreateBetOutcome struct {
@ -34,22 +36,13 @@ type CreateBetOutcome struct {
Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"`
}
type BetStatus int
const (
BET_STATUS_PENDING BetStatus = iota
BET_STATUS_WIN
BET_STATUS_LOSS
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 {
ID int64
Amount Currency
TotalOdds float32
Status BetStatus
Status OutcomeStatus
FullName string
PhoneNumber string
BranchID ValidInt64 // Can Be Nullable
@ -63,7 +56,7 @@ type GetBet struct {
ID int64
Amount Currency
TotalOdds float32
Status BetStatus
Status OutcomeStatus
FullName string
PhoneNumber string
BranchID ValidInt64 // Can Be Nullable
@ -77,7 +70,7 @@ type GetBet struct {
type CreateBet struct {
Amount Currency
TotalOdds float32
Status BetStatus
Status OutcomeStatus
FullName string
PhoneNumber string
BranchID ValidInt64 // Can Be Nullable
@ -86,8 +79,3 @@ type CreateBet struct {
CashoutID string
}
func (b BetStatus) String() string {
return []string{"Pending", "Win", "Loss", "Error"}[b]
}
// func isBetStatusValid()

View File

@ -35,7 +35,17 @@ func (m Currency) String() string {
x := float32(m)
x = x / 100
return fmt.Sprintf("$%.2f", x)
}
type OutcomeStatus int
const (
OUTCOME_STATUS_PENDING OutcomeStatus = iota
OUTCOME_STATUS_WIN
OUTCOME_STATUS_LOSS
OUTCOME_STATUS_ERROR
)
func (b OutcomeStatus) String() string {
return []string{"Pending", "Win", "Loss", "Error"}[b]
}

View File

@ -4,7 +4,18 @@ package domain
// they are the ones that manage the branches and branch managers
// they will have their own wallet that they will use to distribute to the branch wallets
type Company struct {
ID int64
Name string
}
ID int64
Name string
AdminID int64
WalletID int64
}
type CreateCompany struct {
Name string
AdminID int64
WalletID int64
}
type UpdateCompany struct {
Name string
AdminID int64
}

View File

@ -3,19 +3,20 @@ package domain
import "time"
type TicketOutcome struct {
ID int64 `json:"id" example:"1"`
TicketID int64 `json:"ticket_id" example:"1"`
EventID int64 `json:"event_id" example:"1"`
HomeTeamName string `json:"home_team_name" example:"Manchester"`
AwayTeamName string `json:"away_team_name" example:"Liverpool"`
MarketID int64 `json:"market_id" example:"1"`
MarketName string `json:"market_name" example:"Fulltime Result"`
OddID int64 `json:"odd_id" example:"1"`
Odd float32 `json:"odd" example:"1.5"`
OddName string `json:"odd_name" example:"1"`
OddHeader string `json:"odd_header" example:"1"`
OddHandicap string `json:"odd_handicap" example:"1"`
Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"`
ID int64 `json:"id" example:"1"`
TicketID int64 `json:"ticket_id" example:"1"`
EventID int64 `json:"event_id" example:"1"`
HomeTeamName string `json:"home_team_name" example:"Manchester"`
AwayTeamName string `json:"away_team_name" example:"Liverpool"`
MarketID int64 `json:"market_id" example:"1"`
MarketName string `json:"market_name" example:"Fulltime Result"`
OddID int64 `json:"odd_id" example:"1"`
Odd float32 `json:"odd" example:"1.5"`
OddName string `json:"odd_name" example:"1"`
OddHeader string `json:"odd_header" example:"1"`
OddHandicap string `json:"odd_handicap" example:"1"`
Status OutcomeStatus `json:"status" example:"1"`
Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"`
}
type CreateTicketOutcome struct {

View File

@ -14,7 +14,7 @@ func convertDBBet(bet dbgen.Bet) domain.Bet {
ID: bet.ID,
Amount: domain.Currency(bet.Amount),
TotalOdds: bet.TotalOdds,
Status: domain.BetStatus(bet.Status),
Status: domain.OutcomeStatus(bet.Status),
FullName: bet.FullName,
PhoneNumber: bet.PhoneNumber,
BranchID: domain.ValidInt64{
@ -48,6 +48,7 @@ func convertDBBetOutcomes(bet dbgen.BetWithOutcome) domain.GetBet {
OddName: outcome.OddName,
OddHeader: outcome.OddHeader,
OddHandicap: outcome.OddHandicap,
Status: domain.OutcomeStatus(outcome.Status),
Expires: outcome.Expires.Time,
})
}
@ -55,7 +56,7 @@ func convertDBBetOutcomes(bet dbgen.BetWithOutcome) domain.GetBet {
ID: bet.ID,
Amount: domain.Currency(bet.Amount),
TotalOdds: bet.TotalOdds,
Status: domain.BetStatus(bet.Status),
Status: domain.OutcomeStatus(bet.Status),
FullName: bet.FullName,
PhoneNumber: bet.PhoneNumber,
BranchID: domain.ValidInt64{
@ -197,7 +198,7 @@ func (s *Store) UpdateCashOut(ctx context.Context, id int64, cashedOut bool) err
return err
}
func (s *Store) UpdateStatus(ctx context.Context, id int64, status domain.BetStatus) error {
func (s *Store) UpdateStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
err := s.queries.UpdateStatus(ctx, dbgen.UpdateStatusParams{
ID: id,
Status: int32(status),
@ -205,6 +206,14 @@ func (s *Store) UpdateStatus(ctx context.Context, id int64, status domain.BetSta
return err
}
func (s *Store) UpdateBetOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
err := s.queries.UpdateBetOutcomeStatus(ctx, dbgen.UpdateBetOutcomeStatusParams{
Status: int32(status),
ID: id,
})
return err
}
func (s *Store) DeleteBet(ctx context.Context, id int64) error {
return s.queries.DeleteBet(ctx, id)
}

View File

@ -0,0 +1,74 @@
package repository
import (
"context"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
func convertCreateCompany(company domain.CreateCompany) dbgen.CreateCompanyParams {
return dbgen.CreateCompanyParams{
Name: company.Name,
AdminID: company.AdminID,
WalletID: company.WalletID,
}
}
func convertDBCompany(dbCompany dbgen.Company) domain.Company {
return domain.Company{
ID: dbCompany.ID,
Name: dbCompany.Name,
AdminID: dbCompany.AdminID,
WalletID: dbCompany.WalletID,
}
}
func (s *Store) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
dbCompany, err := s.queries.CreateCompany(ctx, convertCreateCompany(company))
if err != nil {
return domain.Company{}, err
}
return convertDBCompany(dbCompany), nil
}
func (s *Store) GetAllCompanies(ctx context.Context) ([]domain.Company, error) {
dbCompanies, err := s.queries.GetAllCompanies(ctx)
if err != nil {
return nil, err
}
var companies []domain.Company = make([]domain.Company, 0, len(dbCompanies))
for _, dbCompany := range dbCompanies {
companies = append(companies, convertDBCompany(dbCompany))
}
return companies, nil
}
func (s *Store) GetCompanyByID(ctx context.Context, id int64) (domain.Company, error) {
dbCompany, err := s.queries.GetCompanyByID(ctx, id)
if err != nil {
return domain.Company{}, err
}
return convertDBCompany(dbCompany), nil
}
func (s *Store) UpdateCompany(ctx context.Context, id int64, company domain.UpdateCompany) (domain.Company, error) {
dbCompany, err := s.queries.UpdateCompany(ctx, dbgen.UpdateCompanyParams{
ID: id,
Name: company.Name,
AdminID: company.AdminID,
})
if err != nil {
return domain.Company{}, err
}
return convertDBCompany(dbCompany), nil
}
func (s *Store) DeleteCompany(ctx context.Context, id int64) error {
return s.queries.DeleteCompany(ctx, id)
}

View File

@ -2,6 +2,7 @@ package repository
import (
"context"
"math"
"time"
dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
@ -87,8 +88,16 @@ func (s *Store) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEven
}
return upcomingEvents, nil
}
func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32) ([]domain.UpcomingEvent, int64, error) {
func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32, leagueID domain.ValidString, sportID domain.ValidString) ([]domain.UpcomingEvent, int64, error) {
events, err := s.queries.GetPaginatedUpcomingEvents(ctx, dbgen.GetPaginatedUpcomingEventsParams{
LeagueID: pgtype.Text{
String: leagueID.Value,
Valid: leagueID.Valid,
},
SportID: pgtype.Text{
String: sportID.Value,
Valid: sportID.Valid,
},
Limit: limit,
Offset: offset * limit,
})
@ -115,13 +124,22 @@ func (s *Store) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, off
StartTime: e.StartTime.Time.UTC(),
}
}
totalCount, err := s.queries.GetTotalEvents(ctx)
totalCount, err := s.queries.GetTotalEvents(ctx, dbgen.GetTotalEventsParams{
LeagueID: pgtype.Text{
String: leagueID.Value,
Valid: leagueID.Valid,
},
SportID: pgtype.Text{
String: sportID.Value,
Valid: sportID.Valid,
},
})
if err != nil {
return nil, 0, err
}
numberOfPages := (totalCount) / int64(limit)
return upcomingEvents, numberOfPages, nil
numberOfPages := math.Ceil(float64(totalCount) / float64(limit))
return upcomingEvents, int64(numberOfPages), nil
}
func (s *Store) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) {
event, err := s.queries.GetUpcomingByID(ctx, ID)

View File

@ -34,6 +34,7 @@ func convertDBTicketOutcomes(ticket dbgen.TicketWithOutcome) domain.GetTicket {
OddName: outcome.OddName,
OddHeader: outcome.OddHeader,
OddHandicap: outcome.OddHandicap,
Status: domain.OutcomeStatus(outcome.Status),
Expires: outcome.Expires.Time,
})
}
@ -122,6 +123,14 @@ func (s *Store) GetAllTickets(ctx context.Context) ([]domain.GetTicket, error) {
return result, nil
}
func (s *Store) UpdateTicketOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
err := s.queries.UpdateTicketOutcomeStatus(ctx, dbgen.UpdateTicketOutcomeStatusParams{
Status: int32(status),
ID: id,
})
return err
}
func (s *Store) DeleteOldTickets(ctx context.Context) error {
return s.queries.DeleteOldTickets(ctx)
}

View File

@ -14,6 +14,7 @@ type BetStore interface {
GetAllBets(ctx context.Context) ([]domain.GetBet, error)
GetBetByBranchID(ctx context.Context, BranchID int64) ([]domain.GetBet, error)
UpdateCashOut(ctx context.Context, id int64, cashedOut bool) error
UpdateStatus(ctx context.Context, id int64, status domain.BetStatus) error
UpdateStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error
UpdateBetOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error
DeleteBet(ctx context.Context, id int64) error
}

View File

@ -17,6 +17,7 @@ func NewService(betStore BetStore) *Service {
}
func (s *Service) CreateBet(ctx context.Context, bet domain.CreateBet) (domain.Bet, error) {
return s.betStore.CreateBet(ctx, bet)
}
@ -42,10 +43,14 @@ func (s *Service) UpdateCashOut(ctx context.Context, id int64, cashedOut bool) e
return s.betStore.UpdateCashOut(ctx, id, cashedOut)
}
func (s *Service) UpdateStatus(ctx context.Context, id int64, status domain.BetStatus) error {
func (s *Service) UpdateStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
return s.betStore.UpdateStatus(ctx, id, status)
}
func (s *Service) UpdateBetOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
return s.betStore.UpdateBetOutcomeStatus(ctx, id, status)
}
func (s *Service) DeleteBet(ctx context.Context, id int64) error {
return s.betStore.DeleteBet(ctx, id)
}

View File

@ -0,0 +1,15 @@
package company
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type CompanyStore interface {
CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error)
GetAllCompanies(ctx context.Context) ([]domain.Company, error)
GetCompanyByID(ctx context.Context, id int64) (domain.Company, error)
UpdateCompany(ctx context.Context, id int64, company domain.UpdateCompany) (domain.Company, error)
DeleteCompany(ctx context.Context, id int64) error
}

View File

@ -0,0 +1,35 @@
package company
import (
"context"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)
type Service struct {
companyStore CompanyStore
}
func NewService(companyStore CompanyStore) *Service {
return &Service{
companyStore: companyStore,
}
}
func (s *Service) CreateCompany(ctx context.Context, company domain.CreateCompany) (domain.Company, error) {
return s.companyStore.CreateCompany(ctx, company)
}
func (s *Service) GetAllCompanies(ctx context.Context) ([]domain.Company, error) {
return s.companyStore.GetAllCompanies(ctx)
}
func (s *Service) GetCompanyByID(ctx context.Context, id int64) (domain.Company, error) {
return s.companyStore.GetCompanyByID(ctx, id)
}
func (s *Service) UpdateCompany(ctx context.Context, id int64, company domain.UpdateCompany) (domain.Company, error) {
return s.companyStore.UpdateCompany(ctx, id, company)
}
func (s *Service) DeleteCompany(ctx context.Context, id int64) error {
return s.companyStore.DeleteCompany(ctx, id)
}

View File

@ -10,6 +10,6 @@ type Service interface {
FetchLiveEvents(ctx context.Context) error
FetchUpcomingEvents(ctx context.Context) error
GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEvent, error)
GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32) ([]domain.UpcomingEvent, int64, error)
GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32, leagueID domain.ValidString, sportID domain.ValidString) ([]domain.UpcomingEvent, int64, error)
GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error)
}

View File

@ -178,8 +178,8 @@ func (s *service) GetAllUpcomingEvents(ctx context.Context) ([]domain.UpcomingEv
return s.store.GetAllUpcomingEvents(ctx)
}
func (s *service) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32) ([]domain.UpcomingEvent, int64, error) {
return s.store.GetPaginatedUpcomingEvents(ctx, limit, offset)
func (s *service) GetPaginatedUpcomingEvents(ctx context.Context, limit int32, offset int32, leagueID domain.ValidString, sportID domain.ValidString) ([]domain.UpcomingEvent, int64, error) {
return s.store.GetPaginatedUpcomingEvents(ctx, limit, offset, leagueID, sportID)
}
func (s *service) GetUpcomingEventByID(ctx context.Context, ID string) (domain.UpcomingEvent, error) {

View File

@ -11,6 +11,7 @@ type TicketStore interface {
CreateTicketOutcome(ctx context.Context, outcomes []domain.CreateTicketOutcome) (int64, error)
GetTicketByID(ctx context.Context, id int64) (domain.GetTicket, error)
GetAllTickets(ctx context.Context) ([]domain.GetTicket, error)
UpdateTicketOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error
DeleteOldTickets(ctx context.Context) error
DeleteTicket(ctx context.Context, id int64) error
}

View File

@ -30,6 +30,10 @@ func (s *Service) GetTicketByID(ctx context.Context, id int64) (domain.GetTicket
func (s *Service) GetAllTickets(ctx context.Context) ([]domain.GetTicket, error) {
return s.ticketStore.GetAllTickets(ctx)
}
func (s *Service) UpdateTicketOutcomeStatus(ctx context.Context, id int64, status domain.OutcomeStatus) error {
return s.ticketStore.UpdateTicketOutcomeStatus(ctx, id, status)
}
func (s *Service) DeleteTicket(ctx context.Context, id int64) error {
return s.ticketStore.DeleteTicket(ctx, id)
}

View File

@ -91,6 +91,8 @@ func (s *Service) DeductFromWallet(ctx context.Context, id int64, amount domain.
return s.walletStore.UpdateBalance(ctx, id, wallet.Balance+amount)
}
func (s *Service) UpdateWalletActive(ctx context.Context, id int64, isActive bool) error {
return s.walletStore.UpdateWalletActive(ctx, id, isActive)
}

View File

@ -7,6 +7,7 @@ import (
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/authentication"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/branch"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
@ -34,6 +35,7 @@ type App struct {
walletSvc *wallet.Service
transactionSvc *transaction.Service
branchSvc *branch.Service
companySvc *company.Service
validator *customvalidator.CustomValidator
JwtConfig jwtutil.JwtConfig
Logger *slog.Logger
@ -52,6 +54,7 @@ func NewApp(
walletSvc *wallet.Service,
transactionSvc *transaction.Service,
branchSvc *branch.Service,
companySvc *company.Service,
notidicationStore notificationservice.NotificationStore,
prematchSvc *odds.ServiceImpl,
eventSvc event.Service,
@ -83,6 +86,7 @@ func NewApp(
walletSvc: walletSvc,
transactionSvc: transactionSvc,
branchSvc: branchSvc,
companySvc: companySvc,
NotidicationStore: notidicationStore,
Logger: logger,
prematchSvc: prematchSvc,

View File

@ -21,82 +21,47 @@ import (
)
type CreateBetOutcomeReq struct {
// BetID int64 `json:"bet_id" example:"1"`
EventID int64 `json:"event_id" example:"1"`
OddID int64 `json:"odd_id" example:"1"`
MarketID int64 `json:"market_id" example:"1"`
// HomeTeamName string `json:"home_team_name" example:"Manchester"`
// AwayTeamName string `json:"away_team_name" example:"Liverpool"`
// MarketName string `json:"market_name" example:"Fulltime Result"`
// Odd float32 `json:"odd" example:"1.5"`
// OddName string `json:"odd_name" example:"1"`
// Expires time.Time `json:"expires" example:"2025-04-08T12:00:00Z"`
}
type NullableInt64 struct {
Value int64
Valid bool
}
func (n *NullableInt64) UnmarshalJSON(data []byte) error {
if string(data) == "null" {
n.Valid = false
return nil
}
var value int64
if err := json.Unmarshal(data, &value); err != nil {
return err
}
n.Value = value
n.Valid = true
return nil
}
func (n NullableInt64) MarshalJSON() ([]byte, error) {
if !n.Valid {
return []byte("null"), nil
}
return json.Marshal(n.Value)
}
type CreateBetReq struct {
Outcomes []CreateBetOutcomeReq `json:"outcomes"`
Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"`
Status domain.BetStatus `json:"status" example:"1"`
Status domain.OutcomeStatus `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 CreateBetRes struct {
ID int64 `json:"id" example:"1"`
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"`
CreatedNumber int64 `json:"created_number" example:"2"`
CashedID string `json:"cashed_id" example:"21234"`
ID int64 `json:"id" example:"1"`
Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"`
Status domain.OutcomeStatus `json:"status" example:"1"`
FullName string `json:"full_name" example:"John"`
PhoneNumber string `json:"phone_number" example:"1234567890"`
BranchID int64 `json:"branch_id" example:"2"`
UserID int64 `json:"user_id" example:"2"`
IsShopBet bool `json:"is_shop_bet" example:"false"`
CreatedNumber int64 `json:"created_number" example:"2"`
CashedID string `json:"cashed_id" example:"21234"`
}
type BetRes struct {
ID int64 `json:"id" example:"1"`
Outcomes []domain.BetOutcome `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"`
CashedOut bool `json:"cashed_out" example:"false"`
CashedID string `json:"cashed_id" example:"21234"`
ID int64 `json:"id" example:"1"`
Outcomes []domain.BetOutcome `json:"outcomes"`
Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"`
Status domain.OutcomeStatus `json:"status" example:"1"`
FullName string `json:"full_name" example:"John"`
PhoneNumber string `json:"phone_number" example:"1234567890"`
BranchID int64 `json:"branch_id" example:"2"`
UserID int64 `json:"user_id" example:"2"`
IsShopBet bool `json:"is_shop_bet" example:"false"`
CashedOut bool `json:"cashed_out" example:"false"`
CashedID string `json:"cashed_id" example:"21234"`
}
func convertCreateBet(bet domain.Bet, createdNumber int64) CreateBetRes {
@ -152,15 +117,12 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateBetReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
// Validating user by role
@ -174,9 +136,7 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
branch, err := branchSvc.GetBranchByCashier(c.Context(), user.ID)
if err != nil {
logger.Error("CreateBetReq failed, branch id invalid")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Branch ID invalid",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
// Deduct a percentage of the amount
@ -186,9 +146,7 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
if err != nil {
logger.Error("CreateBetReq failed, unable to deduct from WalletID")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Unable to deduct from branch wallet",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
bet, err = betSvc.CreateBet(c.Context(), domain.CreateBet{
@ -240,8 +198,7 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
// TODO Validate Outcomes Here and make sure they didn't expire
// Validation for creating tickets
if len(req.Outcomes) > 30 {
response.WriteJSON(c, fiber.StatusBadRequest, "Too many odds/outcomes selected", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Too many odds/outcomes selected", nil, nil)
}
var outcomes []domain.CreateBetOutcome = make([]domain.CreateBetOutcome, 0, len(req.Outcomes))
for _, outcome := range req.Outcomes {
@ -250,22 +207,19 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
oddIDStr := strconv.FormatInt(outcome.OddID, 10)
event, err := eventSvc.GetUpcomingEventByID(c.Context(), eventIDStr)
if err != nil {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid event id", err, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid event id", err, nil)
}
// Checking to make sure the event hasn't already started
currentTime := time.Now()
if event.StartTime.Before(currentTime) {
response.WriteJSON(c, fiber.StatusBadRequest, "The event has already expired", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "The event has already expired", nil, nil)
}
odds, err := oddSvc.GetRawOddsByMarketID(c.Context(), marketIDStr, eventIDStr)
if err != nil {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid market id", err, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid market id", err, nil)
}
type rawOddType struct {
ID string
@ -291,8 +245,7 @@ func CreateBet(logger *slog.Logger, betSvc *bet.Service, userSvc *user.Service,
}
if !isOddFound {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid odd id", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid odd id", nil, nil)
}
parsedOdd, err := strconv.ParseFloat(selectedOdd.Odds, 32)
@ -454,15 +407,12 @@ func UpdateCashOut(logger *slog.Logger, betSvc *bet.Service,
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",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
err = betSvc.UpdateCashOut(c.Context(), id, req.CashedOut)

View File

@ -116,15 +116,12 @@ func CreateBranch(logger *slog.Logger, branchSvc *branch.Service, walletSvc *wal
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateBranchReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
// Create Branch Wallet
@ -194,14 +191,12 @@ func CreateSupportedOperation(logger *slog.Logger, branchSvc *branch.Service, va
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateSupportedOperationReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
operation, err := branchSvc.CreateSupportedOperation(c.Context(), domain.CreateSupportedOperation{
Name: req.Name,
@ -241,15 +236,12 @@ func CreateBranchOperation(logger *slog.Logger, branchSvc *branch.Service, valid
var req CreateBranchOperationReq
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateBranchOperationReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
err := branchSvc.CreateBranchOperation(c.Context(), domain.CreateBranchOperation{
@ -383,6 +375,7 @@ func GetBranchByCompanyID(logger *slog.Logger, branchSvc *branch.Service, valida
// @Router /branch [get]
func GetAllBranches(logger *slog.Logger, branchSvc *branch.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
// TODO: Limit the get all branches to only the companies for branch manager and cashiers
branches, err := branchSvc.GetAllBranches(c.Context())
if err != nil {
logger.Error("Failed to get branches", "error", err)
@ -566,14 +559,11 @@ func UpdateBranch(logger *slog.Logger, branchSvc *branch.Service, validator *cus
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateBranchReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
branch, err := branchSvc.UpdateBranch(c.Context(), id, domain.UpdateBranch{

View File

@ -40,14 +40,11 @@ func CreateCashier(logger *slog.Logger, userSvc *user.Service, branchSvc *branch
var req CreateCashierReq
if err := c.BodyParser(&req); err != nil {
logger.Error("RegisterUser failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
userRequest := domain.CreateUserReq{
FirstName: req.FirstName,
@ -60,19 +57,15 @@ func CreateCashier(logger *slog.Logger, userSvc *user.Service, branchSvc *branch
newUser, err := userSvc.CreateUser(c.Context(), userRequest)
if err != nil {
logger.Error("CreateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create cashier", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create cashier", nil, nil)
}
err = branchSvc.CreateBranchCashier(c.Context(), req.BranchID, newUser.ID)
if err != nil {
logger.Error("CreateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create cashier", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create cashier", nil, nil)
}
response.WriteJSON(c, fiber.StatusOK, "Cashier created successfully", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusOK, "Cashier created successfully", nil, nil)
}
}
@ -119,15 +112,13 @@ func GetAllCashiers(logger *slog.Logger, userSvc *user.Service, validator *custo
// }
// valErrs, ok := validator.Validate(c, filter)
// if !ok {
// response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
// return nil
// return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
// }
cashiers, err := userSvc.GetAllCashiers(c.Context())
if err != nil {
logger.Error("GetAllCashiers failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get cashiers", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get cashiers", nil, nil)
}
var result []GetCashierRes
@ -148,8 +139,8 @@ func GetAllCashiers(logger *slog.Logger, userSvc *user.Service, validator *custo
Suspended: cashier.Suspended,
})
}
response.WriteJSON(c, fiber.StatusOK, "Cashiers retrieved successfully", result, nil)
return nil
return response.WriteJSON(c, fiber.StatusOK, "Cashiers retrieved successfully", result, nil)
}
}
@ -177,22 +168,19 @@ func UpdateCashier(logger *slog.Logger, userSvc *user.Service, validator *custom
var req updateUserReq
if err := c.BodyParser(&req); err != nil {
logger.Error("UpdateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
cashierIdStr := c.Params("id")
cashierId, err := strconv.ParseInt(cashierIdStr, 10, 64)
if err != nil {
logger.Error("UpdateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid cashier ID", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid cashier ID", nil, nil)
}
err = userSvc.UpdateUser(c.Context(), domain.UpdateUserReq{
UserId: cashierId,
@ -212,11 +200,9 @@ func UpdateCashier(logger *slog.Logger, userSvc *user.Service, validator *custom
)
if err != nil {
logger.Error("UpdateCashier failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update cashier", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update cashier", nil, nil)
}
response.WriteJSON(c, fiber.StatusOK, "Cashier updated successfully", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusOK, "Cashier updated successfully", nil, nil)
}
}

View File

@ -0,0 +1,229 @@
package handlers
import (
"log/slog"
"strconv"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/company"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/wallet"
"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 CreateCompanyReq struct {
Name string `json:"name" example:"CompanyName"`
AdminID int64 `json:"admin_id" example:"1"`
}
type CompanyRes struct {
ID int64 `json:"id" example:"1"`
Name string `json:"name" example:"CompanyName"`
AdminID int64 `json:"admin_id" example:"1"`
WalletID int64 `json:"wallet_id" example:"1"`
}
func convertCompany(company domain.Company) CompanyRes {
return CompanyRes{
ID: company.ID,
Name: company.Name,
AdminID: company.AdminID,
WalletID: company.WalletID,
}
}
// CreateCompany godoc
// @Summary Create a company
// @Description Creates a company
// @Tags company
// @Accept json
// @Produce json
// @Param createCompany body CreateCompanyReq true "Creates company"
// @Success 200 {object} CompanyRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /company [post]
func CreateCompany(logger *slog.Logger, companySvc *company.Service, walletSvc *wallet.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
var req CreateCompanyReq
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateCompanyReq failed", "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
// Create Branch Wallet
newWallet, err := walletSvc.CreateWallet(c.Context(), domain.CreateWallet{
IsWithdraw: false,
IsBettable: true,
IsTransferable: true,
UserID: req.AdminID,
})
if err != nil {
logger.Error("Create Company Wallet failed", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create company wallet", err, nil)
}
company, err := companySvc.CreateCompany(c.Context(), domain.CreateCompany{
Name: req.Name,
AdminID: req.AdminID,
WalletID: newWallet.ID,
})
if err != nil {
logger.Error("CreateCompanyReq failed", "error", err)
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Internal server error",
})
}
res := convertCompany(company)
return response.WriteJSON(c, fiber.StatusCreated, "Company Created", res, nil)
}
}
// GetAllCompanies godoc
// @Summary Gets all companies
// @Description Gets all companies
// @Tags company
// @Accept json
// @Produce json
// @Success 200 {array} CompanyRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /company [get]
func GetAllCompanies(logger *slog.Logger, companySvc *company.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
companies, err := companySvc.GetAllCompanies(c.Context())
if err != nil {
logger.Error("Failed to get companies", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get companies", err, nil)
}
var result []CompanyRes = make([]CompanyRes, 0, len(companies))
for _, company := range companies {
result = append(result, convertCompany(company))
}
return response.WriteJSON(c, fiber.StatusOK, "All Companies retrieved", result, nil)
}
}
// GetCompanyByID godoc
// @Summary Gets company by id
// @Description Gets a single company by id
// @Tags company
// @Accept json
// @Produce json
// @Param id path int true "Company ID"
// @Success 200 {object} CompanyRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /company/{id} [get]
func GetCompanyByID(logger *slog.Logger, companySvc *company.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
companyID := c.Params("id")
id, err := strconv.ParseInt(companyID, 10, 64)
if err != nil {
logger.Error("Invalid company ID", "companyID", companyID, "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid company ID", err, nil)
}
company, err := companySvc.GetCompanyByID(c.Context(), id)
if err != nil {
logger.Error("Failed to get company by ID", "companyID", id, "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to company branch", err, nil)
}
res := convertCompany(company)
return response.WriteJSON(c, fiber.StatusOK, "Company retrieved successfully", res, nil)
}
}
// UpdateCompany godoc
// @Summary Updates a company
// @Description Updates a company
// @Tags company
// @Accept json
// @Produce json
// @Param id path int true "Company ID"
// @Param updateCompany body CreateCompanyReq true "Update Company"
// @Success 200 {object} CompanyRes
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /company/{id} [put]
func UpdateCompany(logger *slog.Logger, companySvc *company.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
companyID := c.Params("id")
id, err := strconv.ParseInt(companyID, 10, 64)
if err != nil {
logger.Error("Invalid company ID", "companyID", companyID, "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid company ID", err, nil)
}
var req CreateCompanyReq
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateCompanyReq failed", "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
company, err := companySvc.UpdateCompany(c.Context(), id, domain.UpdateCompany{
Name: req.Name,
AdminID: req.AdminID,
})
if err != nil {
logger.Error("Failed to update company", "companyID", id, "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update company", err, nil)
}
res := convertCompany(company)
return response.WriteJSON(c, fiber.StatusOK, "Company Updated", res, nil)
}
}
// DeleteCompany godoc
// @Summary Delete the company
// @Description Delete the company
// @Tags company
// @Accept json
// @Produce json
// @Param id path int true "Company ID""
// @Success 200 {object} response.APIResponse
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /company/{id} [delete]
func DeleteCompany(logger *slog.Logger, companySvc *company.Service, validator *customvalidator.CustomValidator) fiber.Handler {
return func(c *fiber.Ctx) error {
companyID := c.Params("id")
id, err := strconv.ParseInt(companyID, 10, 64)
if err != nil {
logger.Error("Invalid Company ID", "companyID", companyID, "error", err)
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid Company ID", err, nil)
}
err = companySvc.DeleteCompany(c.Context(), id)
if err != nil {
logger.Error("Failed to delete by ID", "Company ID", id, "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to Delete Company", err, nil)
}
return response.WriteJSON(c, fiber.StatusOK, "Company removed successfully", nil, nil)
}
}

View File

@ -36,14 +36,11 @@ func CreateManager(logger *slog.Logger, userSvc *user.Service, validator *custom
var req CreateManagerReq
if err := c.BodyParser(&req); err != nil {
logger.Error("RegisterUser failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
user := domain.CreateUserReq{
FirstName: req.FirstName,
@ -56,11 +53,9 @@ func CreateManager(logger *slog.Logger, userSvc *user.Service, validator *custom
_, err := userSvc.CreateUser(c.Context(), user)
if err != nil {
logger.Error("CreateManagers failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create Managers", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to create Managers", nil, nil)
}
response.WriteJSON(c, fiber.StatusOK, "Managers created successfully", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusOK, "Managers created successfully", nil, nil)
}
}
@ -91,17 +86,15 @@ func GetAllManagers(logger *slog.Logger, userSvc *user.Service, validator *custo
}
valErrs, ok := validator.Validate(c, filter)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
Managers, err := userSvc.GetAllUsers(c.Context(), filter)
if err != nil {
logger.Error("GetAllManagers failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get Managers", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get Managers", nil, nil)
}
response.WriteJSON(c, fiber.StatusOK, "Managers retrieved successfully", Managers, nil)
return nil
return response.WriteJSON(c, fiber.StatusOK, "Managers retrieved successfully", Managers, nil)
}
}
@ -123,22 +116,19 @@ func UPdateManagers(logger *slog.Logger, userSvc *user.Service, validator *custo
var req updateUserReq
if err := c.BodyParser(&req); err != nil {
logger.Error("UpdateManagers failed", "error", err)
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", nil, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
ManagersIdStr := c.Params("id")
ManagersId, err := strconv.ParseInt(ManagersIdStr, 10, 64)
if err != nil {
logger.Error("UpdateManagers failed", "error", err)
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid Managers ID", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid Managers ID", nil, nil)
}
err = userSvc.UpdateUser(c.Context(), domain.UpdateUserReq{
UserId: ManagersId,
@ -158,11 +148,9 @@ func UPdateManagers(logger *slog.Logger, userSvc *user.Service, validator *custo
)
if err != nil {
logger.Error("UpdateManagers failed", "error", err)
response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update Managers", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to update Managers", nil, nil)
}
response.WriteJSON(c, fiber.StatusOK, "Managers updated successfully", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusOK, "Managers updated successfully", nil, nil)
}
}

View File

@ -4,6 +4,7 @@ import (
"log/slog"
"strconv"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response"
@ -98,6 +99,8 @@ func GetRawOddsByMarketID(logger *slog.Logger, prematchSvc *odds.ServiceImpl) fi
// @Produce json
// @Param page query int false "Page number"
// @Param page_size query int false "Page size"
// @Param league_id query string false "League ID Filter"
// @Param sport_id query string false "Sport ID Filter"
// @Success 200 {array} domain.UpcomingEvent
// @Failure 500 {object} response.APIResponse
// @Router /prematch/events [get]
@ -105,8 +108,20 @@ func GetAllUpcomingEvents(logger *slog.Logger, eventSvc event.Service) fiber.Han
return func(c *fiber.Ctx) error {
page := c.QueryInt("page", 1)
pageSize := c.QueryInt("page_size", 10)
leagueIDQuery := c.Query("league_id")
sportIDQuery := c.Query("sport_id")
leagueID := domain.ValidString{
Value: leagueIDQuery,
Valid: leagueIDQuery != "",
}
sportID := domain.ValidString{
Value: sportIDQuery,
Valid: sportIDQuery != "",
}
events, total, err := eventSvc.GetPaginatedUpcomingEvents(c.Context(), int32(pageSize), int32(page)-1, leagueID, sportID)
events, total, err := eventSvc.GetPaginatedUpcomingEvents(c.Context(), int32(pageSize), int32(page) - 1)
if err != nil {
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve all upcoming events", nil, nil)
}

View File

@ -38,6 +38,12 @@ type CreateTicketRes struct {
FastCode int64 `json:"fast_code" example:"1234"`
CreatedNumber int64 `json:"created_number" example:"3"`
}
type TicketRes struct {
ID int64 `json:"id" example:"1"`
Outcomes []domain.TicketOutcome `json:"outcomes"`
Amount float32 `json:"amount" example:"100.0"`
TotalOdds float32 `json:"total_odds" example:"4.22"`
}
// CreateTicket godoc
// @Summary Create a temporary ticket
@ -55,22 +61,18 @@ func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service, eventSvc event
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",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
// TODO Validate Outcomes Here and make sure they didn't expire
// Validation for creating tickets
if len(req.Outcomes) > 30 {
response.WriteJSON(c, fiber.StatusBadRequest, "Too many odds/outcomes selected", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Too many odds/outcomes selected", nil, nil)
}
var outcomes []domain.CreateTicketOutcome = make([]domain.CreateTicketOutcome, 0, len(req.Outcomes))
for _, outcome := range req.Outcomes {
@ -79,22 +81,19 @@ func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service, eventSvc event
oddIDStr := strconv.FormatInt(outcome.OddID, 10)
event, err := eventSvc.GetUpcomingEventByID(c.Context(), eventIDStr)
if err != nil {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid event id", err, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid event id", err, nil)
}
// Checking to make sure the event hasn't already started
currentTime := time.Now()
if event.StartTime.Before(currentTime) {
response.WriteJSON(c, fiber.StatusBadRequest, "The event has already expired", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "The event has already expired", nil, nil)
}
odds, err := oddSvc.GetRawOddsByMarketID(c.Context(), marketIDStr, eventIDStr)
if err != nil {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid market id", err, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid market id", err, nil)
}
type rawOddType struct {
ID string
@ -120,8 +119,7 @@ func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service, eventSvc event
}
if !isOddFound {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid odd id", nil, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid odd id", nil, nil)
}
parsedOdd, err := strconv.ParseFloat(selectedOdd.Odds, 32)
@ -173,13 +171,6 @@ func CreateTicket(logger *slog.Logger, ticketSvc *ticket.Service, eventSvc event
}
}
type TicketRes struct {
ID int64 `json:"id" example:"1"`
Outcomes []domain.TicketOutcome `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

View File

@ -97,9 +97,7 @@ func CreateTransaction(logger *slog.Logger, transactionSvc *transaction.Service,
branch, err := branchSvc.GetBranchByID(c.Context(), 1)
if err != nil {
logger.Error("CreateTransactionReq no branches")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "This user type doesn't have branches",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "This user type doesn't have branches", err, nil)
}
branchID = branch.ID
@ -108,9 +106,7 @@ func CreateTransaction(logger *slog.Logger, transactionSvc *transaction.Service,
branch, err := branchSvc.GetBranchByCashier(c.Context(), user.ID)
if err != nil {
logger.Error("CreateTransactionReq failed, branch id invalid")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Branch ID invalid",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Branch ID invalid", err, nil)
}
branchID = branch.ID
}
@ -118,16 +114,13 @@ func CreateTransaction(logger *slog.Logger, transactionSvc *transaction.Service,
var req CreateTransactionReq
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateTransactionReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
logger.Error("CreateTransactionReq failed v", "error", valErrs)
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
transaction, err := transactionSvc.CreateTransaction(c.Context(), domain.CreateTransaction{
@ -288,15 +281,12 @@ func UpdateTransactionVerified(logger *slog.Logger, transactionSvc *transaction.
var req UpdateTransactionVerifiedReq
if err := c.BodyParser(&req); err != nil {
logger.Error("UpdateTransactionVerifiedReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
err = transactionSvc.UpdateTransactionVerified(c.Context(), id, req.Verified)

View File

@ -158,22 +158,18 @@ func TransferToWallet(logger *slog.Logger, walletSvc *wallet.Service, branchSvc
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateTransferReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
transfer, err := walletSvc.TransferToWallet(c.Context(), senderID, receiverID, domain.ToCurrency(req.Amount), domain.PaymentMethod(req.PaymentMethod), domain.ValidInt64{Value: userID, Valid: true})
if !ok {
response.WriteJSON(c, fiber.StatusInternalServerError, "Transfer Failed", err, nil)
return nil
return response.WriteJSON(c, fiber.StatusInternalServerError, "Transfer Failed", err, nil)
}
res := convertTransfer(transfer)
@ -218,15 +214,12 @@ func RefillWallet(logger *slog.Logger, walletSvc *wallet.Service, validator *cus
if err := c.BodyParser(&req); err != nil {
logger.Error("CreateRefillReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
valErrs, ok := validator.Validate(c, req)
if !ok {
response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
return nil
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", valErrs, nil)
}
transfer, err := walletSvc.RefillWallet(c.Context(), domain.CreateTransfer{
@ -241,8 +234,7 @@ func RefillWallet(logger *slog.Logger, walletSvc *wallet.Service, validator *cus
})
if !ok {
response.WriteJSON(c, fiber.StatusInternalServerError, "Creating Transfer Failed", err, nil)
return nil
return response.WriteJSON(c, fiber.StatusInternalServerError, "Creating Transfer Failed", err, nil)
}
res := convertTransfer(transfer)

View File

@ -213,9 +213,7 @@ func UpdateWalletActive(logger *slog.Logger, walletSvc *wallet.Service, validato
var req UpdateWalletActiveReq
if err := c.BodyParser(&req); err != nil {
logger.Error("UpdateWalletActiveReq failed", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request",
})
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid request", err, nil)
}
err = walletSvc.UpdateWalletActive(c.Context(), id, req.IsActive)
@ -249,7 +247,7 @@ func GetCustomerWallet(logger *slog.Logger, walletSvc *wallet.Service, validator
vendorID, err := strconv.ParseInt(c.Get("vendor_id"), 10, 64)
if err != nil {
return c.Status(fiber.StatusBadRequest).SendString("Invalid company_id")
return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid company_id", err, nil)
}
logger.Info("Company ID: " + strconv.FormatInt(vendorID, 10))

View File

@ -47,9 +47,13 @@ func (a *App) authMiddleware(c *fiber.Ctx) error {
c.Locals("branch_id", claim.BranchId)
c.Locals("refresh_token", refreshToken)
if claim.Role != domain.RoleCustomer {
// TODO: Add branch id here from the user
// c.Locals("branch_id", claim.)
return c.Next()
}
func (a *App) SuperAdminOnly(c *fiber.Ctx) error {
userRole := c.Locals("role").(domain.Role)
if userRole != domain.RoleSuperAdmin {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid access token")
}
return c.Next()
}

View File

@ -25,7 +25,6 @@ func (a *App) initAppRoutes() {
if err != nil {
return c.Status(fiber.StatusBadRequest).SendString("Invalid company_id")
}
// a.logger.Info("User ID: " + string(userId.(string))) //panic: interface conversion: interface {} is int64, not string
a.logger.Info("User ID: " + strconv.FormatInt(userId, 10))
fmt.Printf("User ID: %d\n", userId)
a.logger.Info("Role: " + role)
@ -85,6 +84,13 @@ func (a *App) initAppRoutes() {
a.fiber.Get("/branch/:id/operation", a.authMiddleware, handlers.GetBranchOperations(a.logger, a.branchSvc, a.validator))
a.fiber.Delete("/branch/:id/operation/:opID", a.authMiddleware, handlers.DeleteBranchOperation(a.logger, a.branchSvc, a.validator))
// Company
a.fiber.Post("/company", a.authMiddleware, a.SuperAdminOnly, handlers.CreateCompany(a.logger, a.companySvc, a.walletSvc, a.validator))
a.fiber.Get("/company", a.authMiddleware, a.SuperAdminOnly, handlers.GetAllCompanies(a.logger, a.companySvc, a.validator))
a.fiber.Get("/company/:id", a.authMiddleware, a.SuperAdminOnly, handlers.GetCompanyByID(a.logger, a.companySvc, a.validator))
a.fiber.Put("/company/:id", a.authMiddleware, a.SuperAdminOnly, handlers.UpdateCompany(a.logger, a.companySvc, a.validator))
a.fiber.Delete("/company/:id", a.authMiddleware, a.SuperAdminOnly, handlers.DeleteCompany(a.logger, a.companySvc, a.validator))
// Ticket
a.fiber.Post("/ticket", handlers.CreateTicket(a.logger, a.ticketSvc, a.eventSvc, *a.prematchSvc, a.validator))
a.fiber.Get("/ticket", handlers.GetAllTickets(a.logger, a.ticketSvc, a.validator))