From 8f2713b920fcf2439721e61200cd66fc9f58b025 Mon Sep 17 00:00:00 2001 From: Yared Yemane Date: Mon, 9 Jun 2025 21:33:58 +0300 Subject: [PATCH] duplicate user creation fix + sender balance check during wallet refill --- db/migrations/000001_fortune.up.sql | 26 ++-- db/migrations/000002_notification.up.sql | 2 +- db/query/monitor.sql | 4 +- db/query/user.sql | 43 +++---- gen/db/branch.sql.go | 24 ++-- gen/db/models.go | 48 ++++--- gen/db/monitor.sql.go | 131 ++++++++++++++++++++ gen/db/transactions.sql.go | 36 +++--- gen/db/user.sql.go | 42 +++---- internal/domain/branch.go | 2 + internal/domain/user.go | 6 +- internal/repository/transaction.go | 64 +++++----- internal/services/wallet/transfer.go | 7 ++ internal/web_server/handlers/mongoLogger.go | 1 + 14 files changed, 294 insertions(+), 142 deletions(-) create mode 100644 gen/db/monitor.sql.go diff --git a/db/migrations/000001_fortune.up.sql b/db/migrations/000001_fortune.up.sql index 5c13e03..a36f82a 100644 --- a/db/migrations/000001_fortune.up.sql +++ b/db/migrations/000001_fortune.up.sql @@ -260,6 +260,7 @@ FROM companies JOIN wallets ON wallets.id = companies.wallet_id JOIN users ON users.id = companies.admin_id; ; + CREATE VIEW branch_details AS SELECT branches.*, CONCAT(users.first_name, ' ', users.last_name) AS manager_name, @@ -284,37 +285,40 @@ FROM tickets LEFT JOIN ticket_outcomes ON tickets.id = ticket_outcomes.ticket_id GROUP BY tickets.id; -- Foreign Keys + +ALTER TABLE users + ADD CONSTRAINT unique_email UNIQUE (email), + ADD CONSTRAINT unique_phone_number UNIQUE (phone_number); ALTER TABLE refresh_tokens -ADD CONSTRAINT fk_refresh_tokens_users FOREIGN KEY (user_id) REFERENCES users(id); + ADD CONSTRAINT fk_refresh_tokens_users FOREIGN KEY (user_id) REFERENCES users(id); ALTER TABLE bets -ADD CONSTRAINT fk_bets_users FOREIGN KEY (user_id) REFERENCES users(id), + ADD CONSTRAINT fk_bets_users FOREIGN KEY (user_id) REFERENCES users(id), ADD CONSTRAINT fk_bets_branches FOREIGN KEY (branch_id) REFERENCES branches(id); ALTER TABLE wallets -ADD CONSTRAINT fk_wallets_users FOREIGN KEY (user_id) REFERENCES users(id); + ADD CONSTRAINT fk_wallets_users FOREIGN KEY (user_id) REFERENCES users(id); ALTER TABLE customer_wallets -ADD CONSTRAINT fk_customer_wallets_customers FOREIGN KEY (customer_id) REFERENCES users(id), + ADD CONSTRAINT fk_customer_wallets_customers FOREIGN KEY (customer_id) REFERENCES users(id), ADD CONSTRAINT fk_customer_wallets_regular_wallet FOREIGN KEY (regular_wallet_id) REFERENCES wallets(id), ADD CONSTRAINT fk_customer_wallets_static_wallet FOREIGN KEY (static_wallet_id) REFERENCES wallets(id); ALTER TABLE wallet_transfer -ADD CONSTRAINT fk_wallet_transfer_receiver_wallet FOREIGN KEY (receiver_wallet_id) REFERENCES wallets(id), + ADD CONSTRAINT fk_wallet_transfer_receiver_wallet FOREIGN KEY (receiver_wallet_id) REFERENCES wallets(id), ADD CONSTRAINT fk_wallet_transfer_sender_wallet FOREIGN KEY (sender_wallet_id) REFERENCES wallets(id), ADD CONSTRAINT fk_wallet_transfer_cashier FOREIGN KEY (cashier_id) REFERENCES users(id); ALTER TABLE transactions -ADD CONSTRAINT fk_transactions_branches FOREIGN KEY (branch_id) REFERENCES branches(id), + ADD CONSTRAINT fk_transactions_branches FOREIGN KEY (branch_id) REFERENCES branches(id), ADD CONSTRAINT fk_transactions_cashiers FOREIGN KEY (cashier_id) REFERENCES users(id), ADD CONSTRAINT fk_transactions_bets FOREIGN KEY (bet_id) REFERENCES bets(id); ALTER TABLE branches -ADD CONSTRAINT fk_branches_wallet FOREIGN KEY (wallet_id) REFERENCES wallets(id), + ADD CONSTRAINT fk_branches_wallet FOREIGN KEY (wallet_id) REFERENCES wallets(id), ADD CONSTRAINT fk_branches_manager FOREIGN KEY (branch_manager_id) REFERENCES users(id); ALTER TABLE branch_operations -ADD CONSTRAINT fk_branch_operations_operations FOREIGN KEY (operation_id) REFERENCES supported_operations(id) ON DELETE CASCADE, + ADD CONSTRAINT fk_branch_operations_operations FOREIGN KEY (operation_id) REFERENCES supported_operations(id) ON DELETE CASCADE, ADD CONSTRAINT fk_branch_operations_branches FOREIGN KEY (branch_id) REFERENCES branches(id) ON DELETE CASCADE; ALTER TABLE branch_cashiers -ADD CONSTRAINT fk_branch_cashiers_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, + ADD CONSTRAINT fk_branch_cashiers_users FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, ADD CONSTRAINT fk_branch_cashiers_branches FOREIGN KEY (branch_id) REFERENCES branches(id) ON DELETE CASCADE; - ALTER TABLE companies -ADD CONSTRAINT fk_companies_admin FOREIGN KEY (admin_id) REFERENCES users(id), + ADD CONSTRAINT fk_companies_admin FOREIGN KEY (admin_id) REFERENCES users(id), ADD CONSTRAINT fk_companies_wallet FOREIGN KEY (wallet_id) REFERENCES wallets(id) ON DELETE CASCADE; ----------------------------------------------seed data------------------------------------------------------------- -------------------------------------- DO NOT USE IN PRODUCTION------------------------------------------------- diff --git a/db/migrations/000002_notification.up.sql b/db/migrations/000002_notification.up.sql index 364de0c..bf6a439 100644 --- a/db/migrations/000002_notification.up.sql +++ b/db/migrations/000002_notification.up.sql @@ -37,7 +37,7 @@ CREATE TABLE IF NOT EXISTS wallet_threshold_notifications ( PRIMARY KEY (company_id, threshold) ); -CREATE INDEX idx_wallet_threshold_notifications_company ON wallet_threshold_notifications(company_id) +CREATE INDEX idx_wallet_threshold_notifications_company ON wallet_threshold_notifications(company_id); CREATE INDEX idx_notifications_recipient_id ON notifications (recipient_id); diff --git a/db/query/monitor.sql b/db/query/monitor.sql index a5d21b7..a206539 100644 --- a/db/query/monitor.sql +++ b/db/query/monitor.sql @@ -1,5 +1,5 @@ --- name: GetAllCompanies :many -SELECT id, name, wallet_id, admin_id, created_at +-- name: GetAllCompaniesBranch :many +SELECT id, name, wallet_id, admin_id FROM companies; -- name: GetBranchesByCompanyID :many diff --git a/db/query/user.sql b/db/query/user.sql index 91ddccb..515bfe8 100644 --- a/db/query/user.sql +++ b/db/query/user.sql @@ -1,32 +1,22 @@ -- name: CreateUser :one INSERT INTO users ( - first_name, - last_name, - email, - phone_number, - role, - password, - email_verified, - phone_verified, - created_at, - updated_at, - suspended, - company_id - ) + first_name, + last_name, + email, + phone_number, + role, + password, + email_verified, + phone_verified, + created_at, + updated_at, + suspended, + company_id +) VALUES ( - $1, - $2, - $3, - $4, - $5, - $6, - $7, - $8, - $9, - $10, - $11, - $12 - ) + $1, $2, $3, $4, $5, $6, + $7, $8, $9, $10, $11, $12 +) RETURNING id, first_name, last_name, @@ -39,6 +29,7 @@ RETURNING id, updated_at, suspended, company_id; + -- name: GetUserByID :one SELECT * FROM users diff --git a/gen/db/branch.sql.go b/gen/db/branch.sql.go index 5d236d3..57b8dad 100644 --- a/gen/db/branch.sql.go +++ b/gen/db/branch.sql.go @@ -21,7 +21,7 @@ INSERT INTO branches ( is_self_owned ) VALUES ($1, $2, $3, $4, $5, $6) -RETURNING id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at +RETURNING id, name, location, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at ` type CreateBranchParams struct { @@ -47,6 +47,7 @@ func (q *Queries) CreateBranch(ctx context.Context, arg CreateBranchParams) (Bra &i.ID, &i.Name, &i.Location, + &i.IsActive, &i.WalletID, &i.BranchManagerID, &i.CompanyID, @@ -154,7 +155,7 @@ func (q *Queries) DeleteBranchOperation(ctx context.Context, arg DeleteBranchOpe } const GetAllBranches = `-- name: GetAllBranches :many -SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number +SELECT id, name, location, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number FROM branch_details ` @@ -171,6 +172,7 @@ func (q *Queries) GetAllBranches(ctx context.Context) ([]BranchDetail, error) { &i.ID, &i.Name, &i.Location, + &i.IsActive, &i.WalletID, &i.BranchManagerID, &i.CompanyID, @@ -216,7 +218,7 @@ func (q *Queries) GetAllSupportedOperations(ctx context.Context) ([]SupportedOpe } const GetBranchByCashier = `-- name: GetBranchByCashier :one -SELECT branches.id, branches.name, branches.location, branches.wallet_id, branches.branch_manager_id, branches.company_id, branches.is_self_owned, branches.created_at, branches.updated_at +SELECT branches.id, branches.name, branches.location, branches.is_active, branches.wallet_id, branches.branch_manager_id, branches.company_id, branches.is_self_owned, branches.created_at, branches.updated_at FROM branch_cashiers JOIN branches ON branch_cashiers.branch_id = branches.id WHERE branch_cashiers.user_id = $1 @@ -229,6 +231,7 @@ func (q *Queries) GetBranchByCashier(ctx context.Context, userID int64) (Branch, &i.ID, &i.Name, &i.Location, + &i.IsActive, &i.WalletID, &i.BranchManagerID, &i.CompanyID, @@ -240,7 +243,7 @@ func (q *Queries) GetBranchByCashier(ctx context.Context, userID int64) (Branch, } const GetBranchByCompanyID = `-- name: GetBranchByCompanyID :many -SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number +SELECT id, name, location, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number FROM branch_details WHERE company_id = $1 ` @@ -258,6 +261,7 @@ func (q *Queries) GetBranchByCompanyID(ctx context.Context, companyID int64) ([] &i.ID, &i.Name, &i.Location, + &i.IsActive, &i.WalletID, &i.BranchManagerID, &i.CompanyID, @@ -278,7 +282,7 @@ func (q *Queries) GetBranchByCompanyID(ctx context.Context, companyID int64) ([] } const GetBranchByID = `-- name: GetBranchByID :one -SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number +SELECT id, name, location, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number FROM branch_details WHERE id = $1 ` @@ -290,6 +294,7 @@ func (q *Queries) GetBranchByID(ctx context.Context, id int64) (BranchDetail, er &i.ID, &i.Name, &i.Location, + &i.IsActive, &i.WalletID, &i.BranchManagerID, &i.CompanyID, @@ -303,7 +308,7 @@ func (q *Queries) GetBranchByID(ctx context.Context, id int64) (BranchDetail, er } const GetBranchByManagerID = `-- name: GetBranchByManagerID :many -SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number +SELECT id, name, location, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number FROM branch_details WHERE branch_manager_id = $1 ` @@ -321,6 +326,7 @@ func (q *Queries) GetBranchByManagerID(ctx context.Context, branchManagerID int6 &i.ID, &i.Name, &i.Location, + &i.IsActive, &i.WalletID, &i.BranchManagerID, &i.CompanyID, @@ -388,7 +394,7 @@ func (q *Queries) GetBranchOperations(ctx context.Context, branchID int64) ([]Ge } const SearchBranchByName = `-- name: SearchBranchByName :many -SELECT id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number +SELECT id, name, location, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at, manager_name, manager_phone_number FROM branch_details WHERE name ILIKE '%' || $1 || '%' ` @@ -406,6 +412,7 @@ func (q *Queries) SearchBranchByName(ctx context.Context, dollar_1 pgtype.Text) &i.ID, &i.Name, &i.Location, + &i.IsActive, &i.WalletID, &i.BranchManagerID, &i.CompanyID, @@ -433,7 +440,7 @@ SET name = COALESCE($2, name), company_id = COALESCE($5, company_id), is_self_owned = COALESCE($6, is_self_owned) WHERE id = $1 -RETURNING id, name, location, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at +RETURNING id, name, location, is_active, wallet_id, branch_manager_id, company_id, is_self_owned, created_at, updated_at ` type UpdateBranchParams struct { @@ -459,6 +466,7 @@ func (q *Queries) UpdateBranch(ctx context.Context, arg UpdateBranchParams) (Bra &i.ID, &i.Name, &i.Location, + &i.IsActive, &i.WalletID, &i.BranchManagerID, &i.CompanyID, diff --git a/gen/db/models.go b/gen/db/models.go index cac0329..87a6909 100644 --- a/gen/db/models.go +++ b/gen/db/models.go @@ -112,6 +112,7 @@ type Branch struct { ID int64 `json:"id"` Name string `json:"name"` Location string `json:"location"` + IsActive bool `json:"is_active"` WalletID int64 `json:"wallet_id"` BranchManagerID int64 `json:"branch_manager_id"` CompanyID int64 `json:"company_id"` @@ -130,6 +131,7 @@ type BranchDetail struct { ID int64 `json:"id"` Name string `json:"name"` Location string `json:"location"` + IsActive bool `json:"is_active"` WalletID int64 `json:"wallet_id"` BranchManagerID int64 `json:"branch_manager_id"` CompanyID int64 `json:"company_id"` @@ -313,6 +315,14 @@ type SupportedOperation struct { Description string `json:"description"` } +type Team struct { + ID string `json:"id"` + TeamName string `json:"team_name"` + Country pgtype.Text `json:"country"` + Bet365ID pgtype.Int4 `json:"bet365_id"` + LogoUrl pgtype.Text `json:"logo_url"` +} + type Ticket struct { ID int64 `json:"id"` Amount int64 `json:"amount"` @@ -351,25 +361,25 @@ type Transaction struct { ID int64 `json:"id"` Amount int64 `json:"amount"` BranchID int64 `json:"branch_id"` - CompanyID int64 `json:"company_id"` - CashierID int64 `json:"cashier_id"` - CashierName string `json:"cashier_name"` - BetID int64 `json:"bet_id"` - NumberOfOutcomes int64 `json:"number_of_outcomes"` - Type int64 `json:"type"` - PaymentOption int64 `json:"payment_option"` - FullName string `json:"full_name"` - PhoneNumber string `json:"phone_number"` - BankCode string `json:"bank_code"` - BeneficiaryName string `json:"beneficiary_name"` - AccountName string `json:"account_name"` - AccountNumber string `json:"account_number"` - ReferenceNumber string `json:"reference_number"` + CompanyID pgtype.Int8 `json:"company_id"` + CashierID pgtype.Int8 `json:"cashier_id"` + CashierName pgtype.Text `json:"cashier_name"` + BetID pgtype.Int8 `json:"bet_id"` + NumberOfOutcomes pgtype.Int8 `json:"number_of_outcomes"` + Type pgtype.Int8 `json:"type"` + PaymentOption pgtype.Int8 `json:"payment_option"` + FullName pgtype.Text `json:"full_name"` + PhoneNumber pgtype.Text `json:"phone_number"` + BankCode pgtype.Text `json:"bank_code"` + BeneficiaryName pgtype.Text `json:"beneficiary_name"` + AccountName pgtype.Text `json:"account_name"` + AccountNumber pgtype.Text `json:"account_number"` + ReferenceNumber pgtype.Text `json:"reference_number"` Verified bool `json:"verified"` ApprovedBy pgtype.Int8 `json:"approved_by"` ApproverName pgtype.Text `json:"approver_name"` - BranchLocation string `json:"branch_location"` - BranchName string `json:"branch_name"` + BranchLocation pgtype.Text `json:"branch_location"` + BranchName pgtype.Text `json:"branch_name"` CreatedAt pgtype.Timestamp `json:"created_at"` UpdatedAt pgtype.Timestamp `json:"updated_at"` } @@ -459,6 +469,12 @@ type Wallet struct { CashBalance pgtype.Numeric `json:"cash_balance"` } +type WalletThresholdNotification struct { + CompanyID int64 `json:"company_id"` + Threshold float64 `json:"threshold"` + NotifiedAt pgtype.Timestamptz `json:"notified_at"` +} + type WalletTransfer struct { ID int64 `json:"id"` Amount int64 `json:"amount"` diff --git a/gen/db/monitor.sql.go b/gen/db/monitor.sql.go new file mode 100644 index 0000000..a9a7ecb --- /dev/null +++ b/gen/db/monitor.sql.go @@ -0,0 +1,131 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.29.0 +// source: monitor.sql + +package dbgen + +import ( + "context" +) + +const CountThresholdNotifications = `-- name: CountThresholdNotifications :one +SELECT COUNT(*) +FROM wallet_threshold_notifications +WHERE company_id = $1 AND threshold = $2 +` + +type CountThresholdNotificationsParams struct { + CompanyID int64 `json:"company_id"` + Threshold float64 `json:"threshold"` +} + +func (q *Queries) CountThresholdNotifications(ctx context.Context, arg CountThresholdNotificationsParams) (int64, error) { + row := q.db.QueryRow(ctx, CountThresholdNotifications, arg.CompanyID, arg.Threshold) + var count int64 + err := row.Scan(&count) + return count, err +} + +const CreateThresholdNotification = `-- name: CreateThresholdNotification :exec +INSERT INTO wallet_threshold_notifications (company_id, threshold) +VALUES ($1, $2) +` + +type CreateThresholdNotificationParams struct { + CompanyID int64 `json:"company_id"` + Threshold float64 `json:"threshold"` +} + +func (q *Queries) CreateThresholdNotification(ctx context.Context, arg CreateThresholdNotificationParams) error { + _, err := q.db.Exec(ctx, CreateThresholdNotification, arg.CompanyID, arg.Threshold) + return err +} + +const GetAllCompaniesBranch = `-- name: GetAllCompaniesBranch :many +SELECT id, name, wallet_id, admin_id +FROM companies +` + +type GetAllCompaniesBranchRow struct { + ID int64 `json:"id"` + Name string `json:"name"` + WalletID int64 `json:"wallet_id"` + AdminID int64 `json:"admin_id"` +} + +func (q *Queries) GetAllCompaniesBranch(ctx context.Context) ([]GetAllCompaniesBranchRow, error) { + rows, err := q.db.Query(ctx, GetAllCompaniesBranch) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetAllCompaniesBranchRow + for rows.Next() { + var i GetAllCompaniesBranchRow + if err := rows.Scan( + &i.ID, + &i.Name, + &i.WalletID, + &i.AdminID, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const GetBranchesByCompanyID = `-- name: GetBranchesByCompanyID :many +SELECT + id, + name, + location, + wallet_id, + branch_manager_id, + company_id, + is_self_owned +FROM branches +WHERE company_id = $1 +` + +type GetBranchesByCompanyIDRow struct { + ID int64 `json:"id"` + Name string `json:"name"` + Location string `json:"location"` + WalletID int64 `json:"wallet_id"` + BranchManagerID int64 `json:"branch_manager_id"` + CompanyID int64 `json:"company_id"` + IsSelfOwned bool `json:"is_self_owned"` +} + +func (q *Queries) GetBranchesByCompanyID(ctx context.Context, companyID int64) ([]GetBranchesByCompanyIDRow, error) { + rows, err := q.db.Query(ctx, GetBranchesByCompanyID, companyID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetBranchesByCompanyIDRow + for rows.Next() { + var i GetBranchesByCompanyIDRow + if err := rows.Scan( + &i.ID, + &i.Name, + &i.Location, + &i.WalletID, + &i.BranchManagerID, + &i.CompanyID, + &i.IsSelfOwned, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/gen/db/transactions.sql.go b/gen/db/transactions.sql.go index 5bce39f..cbd5743 100644 --- a/gen/db/transactions.sql.go +++ b/gen/db/transactions.sql.go @@ -56,24 +56,24 @@ RETURNING id, amount, branch_id, company_id, cashier_id, cashier_name, bet_id, n ` type CreateTransactionParams struct { - Amount int64 `json:"amount"` - BranchID int64 `json:"branch_id"` - CashierID int64 `json:"cashier_id"` - BetID int64 `json:"bet_id"` - Type int64 `json:"type"` - PaymentOption int64 `json:"payment_option"` - FullName string `json:"full_name"` - PhoneNumber string `json:"phone_number"` - BankCode string `json:"bank_code"` - BeneficiaryName string `json:"beneficiary_name"` - AccountName string `json:"account_name"` - AccountNumber string `json:"account_number"` - ReferenceNumber string `json:"reference_number"` - NumberOfOutcomes int64 `json:"number_of_outcomes"` - BranchName string `json:"branch_name"` - BranchLocation string `json:"branch_location"` - CompanyID int64 `json:"company_id"` - CashierName string `json:"cashier_name"` + Amount int64 `json:"amount"` + BranchID int64 `json:"branch_id"` + CashierID pgtype.Int8 `json:"cashier_id"` + BetID pgtype.Int8 `json:"bet_id"` + Type pgtype.Int8 `json:"type"` + PaymentOption pgtype.Int8 `json:"payment_option"` + FullName pgtype.Text `json:"full_name"` + PhoneNumber pgtype.Text `json:"phone_number"` + BankCode pgtype.Text `json:"bank_code"` + BeneficiaryName pgtype.Text `json:"beneficiary_name"` + AccountName pgtype.Text `json:"account_name"` + AccountNumber pgtype.Text `json:"account_number"` + ReferenceNumber pgtype.Text `json:"reference_number"` + NumberOfOutcomes pgtype.Int8 `json:"number_of_outcomes"` + BranchName pgtype.Text `json:"branch_name"` + BranchLocation pgtype.Text `json:"branch_location"` + CompanyID pgtype.Int8 `json:"company_id"` + CashierName pgtype.Text `json:"cashier_name"` } func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionParams) (Transaction, error) { diff --git a/gen/db/user.sql.go b/gen/db/user.sql.go index ca2da1e..89051b2 100644 --- a/gen/db/user.sql.go +++ b/gen/db/user.sql.go @@ -45,33 +45,23 @@ func (q *Queries) CheckPhoneEmailExist(ctx context.Context, arg CheckPhoneEmailE const CreateUser = `-- name: CreateUser :one INSERT INTO users ( - first_name, - last_name, - email, - phone_number, - role, - password, - email_verified, - phone_verified, - created_at, - updated_at, - suspended, - company_id - ) + first_name, + last_name, + email, + phone_number, + role, + password, + email_verified, + phone_verified, + created_at, + updated_at, + suspended, + company_id +) VALUES ( - $1, - $2, - $3, - $4, - $5, - $6, - $7, - $8, - $9, - $10, - $11, - $12 - ) + $1, $2, $3, $4, $5, $6, + $7, $8, $9, $10, $11, $12 +) RETURNING id, first_name, last_name, diff --git a/internal/domain/branch.go b/internal/domain/branch.go index fd7bad6..fe71494 100644 --- a/internal/domain/branch.go +++ b/internal/domain/branch.go @@ -7,6 +7,7 @@ type Branch struct { WalletID int64 BranchManagerID int64 CompanyID int64 + IsSuspended bool IsSelfOwned bool } @@ -17,6 +18,7 @@ type BranchDetail struct { WalletID int64 BranchManagerID int64 CompanyID int64 + IsSuspended bool IsSelfOwned bool ManagerName string ManagerPhoneNumber string diff --git a/internal/domain/user.go b/internal/domain/user.go index bdafe6c..ce9880c 100644 --- a/internal/domain/user.go +++ b/internal/domain/user.go @@ -13,8 +13,8 @@ type User struct { ID int64 FirstName string LastName string - Email string - PhoneNumber string + Email string `json:"email"` + PhoneNumber string `json:"phone_number"` Password []byte Role Role // @@ -29,6 +29,7 @@ type User struct { // CompanyID ValidInt64 } + type RegisterUserReq struct { FirstName string LastName string @@ -62,6 +63,7 @@ type UpdateUserReq struct { FirstName ValidString LastName ValidString Suspended ValidBool + CompanyID ValidInt64 } diff --git a/internal/repository/transaction.go b/internal/repository/transaction.go index e2008b8..edc8184 100644 --- a/internal/repository/transaction.go +++ b/internal/repository/transaction.go @@ -14,18 +14,18 @@ func convertDBTransaction(transaction dbgen.Transaction) domain.Transaction { ID: transaction.ID, Amount: domain.Currency(transaction.Amount), BranchID: transaction.BranchID, - CashierID: transaction.CashierID, - BetID: transaction.BetID, - NumberOfOutcomes: transaction.NumberOfOutcomes, - Type: domain.TransactionType(transaction.Type), - PaymentOption: domain.PaymentOption(transaction.PaymentOption), - FullName: transaction.FullName, - PhoneNumber: transaction.PhoneNumber, - BankCode: transaction.BankCode, - BeneficiaryName: transaction.BeneficiaryName, - AccountName: transaction.AccountName, - AccountNumber: transaction.AccountNumber, - ReferenceNumber: transaction.ReferenceNumber, + CashierID: transaction.CashierID.Int64, + BetID: transaction.BetID.Int64, + NumberOfOutcomes: transaction.NumberOfOutcomes.Int64, + Type: domain.TransactionType(transaction.Type.Int64), + PaymentOption: domain.PaymentOption(transaction.PaymentOption.Int64), + FullName: transaction.FullName.String, + PhoneNumber: transaction.PhoneNumber.String, + BankCode: transaction.BankCode.String, + BeneficiaryName: transaction.BeneficiaryName.String, + AccountName: transaction.AccountName.String, + AccountNumber: transaction.AccountNumber.String, + ReferenceNumber: transaction.ReferenceNumber.String, ApprovedBy: domain.ValidInt64{ Value: transaction.ApprovedBy.Int64, Valid: transaction.ApprovedBy.Valid, @@ -33,10 +33,10 @@ func convertDBTransaction(transaction dbgen.Transaction) domain.Transaction { CreatedAt: transaction.CreatedAt.Time, UpdatedAt: transaction.UpdatedAt.Time, Verified: transaction.Verified, - BranchName: transaction.BranchName, - BranchLocation: transaction.BranchLocation, - CashierName: transaction.CashierName, - CompanyID: transaction.CompanyID, + BranchName: transaction.BranchName.String, + BranchLocation: transaction.BranchLocation.String, + CashierName: transaction.CashierName.String, + CompanyID: transaction.CompanyID.Int64, ApproverName: domain.ValidString{ Value: transaction.ApproverName.String, Valid: transaction.ApprovedBy.Valid, @@ -48,22 +48,22 @@ func convertCreateTransaction(transaction domain.CreateTransaction) dbgen.Create return dbgen.CreateTransactionParams{ Amount: int64(transaction.Amount), BranchID: transaction.BranchID, - CashierID: transaction.CashierID, - BetID: transaction.BetID, - Type: int64(transaction.Type), - PaymentOption: int64(transaction.PaymentOption), - FullName: transaction.FullName, - PhoneNumber: transaction.PhoneNumber, - BankCode: transaction.BankCode, - BeneficiaryName: transaction.BeneficiaryName, - AccountName: transaction.AccountName, - AccountNumber: transaction.AccountNumber, - ReferenceNumber: transaction.ReferenceNumber, - NumberOfOutcomes: transaction.NumberOfOutcomes, - BranchName: transaction.BranchName, - BranchLocation: transaction.BranchLocation, - CashierName: transaction.CashierName, - CompanyID: transaction.CompanyID, + CashierID: pgtype.Int8{Int64: transaction.CashierID, Valid: true}, + BetID: pgtype.Int8{Int64: transaction.BetID, Valid: true}, + Type: pgtype.Int8{Int64: int64(transaction.Type), Valid: true}, + PaymentOption: pgtype.Int8{Int64: int64(transaction.PaymentOption), Valid: true}, + FullName: pgtype.Text{String: transaction.FullName, Valid: transaction.FullName != ""}, + PhoneNumber: pgtype.Text{String: transaction.PhoneNumber, Valid: transaction.PhoneNumber != ""}, + BankCode: pgtype.Text{String: transaction.BankCode, Valid: transaction.BankCode != ""}, + BeneficiaryName: pgtype.Text{String: transaction.BeneficiaryName, Valid: transaction.BeneficiaryName != ""}, + AccountName: pgtype.Text{String: transaction.AccountName, Valid: transaction.AccountName != ""}, + AccountNumber: pgtype.Text{String: transaction.AccountNumber, Valid: transaction.AccountNumber != ""}, + ReferenceNumber: pgtype.Text{String: transaction.ReferenceNumber, Valid: transaction.ReferenceNumber != ""}, + NumberOfOutcomes: pgtype.Int8{Int64: transaction.NumberOfOutcomes, Valid: true}, + BranchName: pgtype.Text{String: transaction.BranchName, Valid: transaction.BranchName != ""}, + BranchLocation: pgtype.Text{String: transaction.BranchLocation, Valid: transaction.BranchLocation != ""}, + CashierName: pgtype.Text{String: transaction.CashierName, Valid: transaction.CashierName != ""}, + CompanyID: pgtype.Int8{Int64: transaction.CompanyID, Valid: true}, } } diff --git a/internal/services/wallet/transfer.go b/internal/services/wallet/transfer.go index 74c2a1b..927120f 100644 --- a/internal/services/wallet/transfer.go +++ b/internal/services/wallet/transfer.go @@ -119,6 +119,13 @@ func (s *Service) RefillWallet(ctx context.Context, transfer domain.CreateTransf } // Add to receiver + senderWallet, err := s.GetWalletByID(ctx, transfer.SenderWalletID.Value) + if err != nil { + return domain.Transfer{}, err + } else if senderWallet.Balance < transfer.Amount { + return domain.Transfer{}, ErrInsufficientBalance + } + err = s.walletStore.UpdateBalance(ctx, receiverWallet.ID, receiverWallet.Balance+transfer.Amount) if err != nil { return domain.Transfer{}, err diff --git a/internal/web_server/handlers/mongoLogger.go b/internal/web_server/handlers/mongoLogger.go index 9f01297..384e3a2 100644 --- a/internal/web_server/handlers/mongoLogger.go +++ b/internal/web_server/handlers/mongoLogger.go @@ -32,6 +32,7 @@ func GetLogsHandler(appCtx context.Context) fiber.Handler { return fiber.NewError(fiber.StatusInternalServerError, "Cursor decoding error: "+err.Error()) } + return c.JSON(logs) } }