From d43b12c589d32e4b6147cfb54a3b939c476bae6f Mon Sep 17 00:00:00 2001 From: Samuel Tariku Date: Tue, 22 Jul 2025 17:39:53 +0300 Subject: [PATCH] integration issues --- db/query/leagues.sql | 2 ++ gen/db/leagues.sql.go | 2 ++ internal/domain/company.go | 1 + internal/domain/issue_reporting.go | 2 +- internal/repository/bet.go | 20 ++++++------ internal/repository/league.go | 2 +- internal/web_server/cron.go | 32 +++++++++---------- .../web_server/handlers/branch_handler.go | 14 ++++---- .../web_server/handlers/company_handler.go | 8 +++-- .../web_server/handlers/issue_reporting.go | 18 ++++++++++- internal/web_server/handlers/leagues.go | 22 +++++++++++-- internal/web_server/handlers/mongoLogger.go | 4 +-- .../handlers/notification_handler.go | 2 +- internal/web_server/handlers/report.go | 7 ++-- internal/web_server/routes.go | 6 ++-- 15 files changed, 92 insertions(+), 50 deletions(-) diff --git a/db/query/leagues.sql b/db/query/leagues.sql index 7aa7623..368da67 100644 --- a/db/query/leagues.sql +++ b/db/query/leagues.sql @@ -41,6 +41,8 @@ WHERE ( is_featured = sqlc.narg('is_featured') OR sqlc.narg('is_featured') IS NULL ) +ORDER BY is_featured DESC, + name ASC LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset'); -- name: GetFeaturedLeagues :many SELECT id, diff --git a/gen/db/leagues.sql.go b/gen/db/leagues.sql.go index fa5da4c..143f6ca 100644 --- a/gen/db/leagues.sql.go +++ b/gen/db/leagues.sql.go @@ -52,6 +52,8 @@ WHERE ( is_featured = $4 OR $4 IS NULL ) +ORDER BY is_featured DESC, + name ASC LIMIT $6 OFFSET $5 ` diff --git a/internal/domain/company.go b/internal/domain/company.go index 406f0fe..ec170be 100644 --- a/internal/domain/company.go +++ b/internal/domain/company.go @@ -112,6 +112,7 @@ func ConvertGetCompany(company GetCompany) GetCompanyRes { AdminFirstName: company.AdminFirstName, AdminLastName: company.AdminLastName, AdminPhoneNumber: company.AdminPhoneNumber, + } } diff --git a/internal/domain/issue_reporting.go b/internal/domain/issue_reporting.go index 59400d3..38ffe76 100644 --- a/internal/domain/issue_reporting.go +++ b/internal/domain/issue_reporting.go @@ -12,7 +12,7 @@ var ( ISSUE_TYPE_ODDS ReportedIssueType = "odds" ISSUE_TYPE_EVENTS ReportedIssueType = "events" ISSUE_TYPE_BRANCH ReportedIssueType = "branch" - ISSUE_TYPE_USER ReportedIssueType = "branch" + ISSUE_TYPE_USER ReportedIssueType = "user" ISSUE_TYPE_LOGIN ReportedIssueType = "login" ISSUE_TYPE_REGISTER ReportedIssueType = "register" ISSUE_TYPE_RESET_PASSWORD ReportedIssueType = "reset_password" diff --git a/internal/repository/bet.go b/internal/repository/bet.go index 2dee7b1..b9391f1 100644 --- a/internal/repository/bet.go +++ b/internal/repository/bet.go @@ -544,16 +544,16 @@ func (s *Store) GetBetSummary(ctx context.Context, filter domain.ReportFilter) ( return 0, 0, 0, 0, 0, 0, fmt.Errorf("failed to get bet summary: %w", err) } - domain.MongoDBLogger.Info("GetBetSummary executed successfully", - zap.String("query", query), - zap.Any("args", args), - zap.Float64("totalStakes", float64(totalStakes)), // convert if needed - zap.Int64("totalBets", totalBets), - zap.Int64("activeBets", activeBets), - zap.Int64("totalWins", totalWins), - zap.Int64("totalLosses", totalLosses), - zap.Float64("winBalance", float64(winBalance)), // convert if needed - ) + // domain.MongoDBLogger.Info("GetBetSummary executed successfully", + // zap.String("query", query), + // zap.Any("args", args), + // zap.Float64("totalStakes", float64(totalStakes)), // convert if needed + // zap.Int64("totalBets", totalBets), + // zap.Int64("activeBets", activeBets), + // zap.Int64("totalWins", totalWins), + // zap.Int64("totalLosses", totalLosses), + // zap.Float64("winBalance", float64(winBalance)), // convert if needed + // ) return totalStakes, totalBets, activeBets, totalWins, totalLosses, winBalance, nil } diff --git a/internal/repository/league.go b/internal/repository/league.go index 4cb9bb6..fa6f870 100644 --- a/internal/repository/league.go +++ b/internal/repository/league.go @@ -123,7 +123,7 @@ func (s *Store) UpdateLeague(ctx context.Context, league domain.UpdateLeague) er }, IsFeatured: pgtype.Bool{ Bool: league.IsFeatured.Value, - Valid: league.IsActive.Valid, + Valid: league.IsFeatured.Valid, }, SportID: pgtype.Int4{ Int32: league.SportID.Value, diff --git a/internal/web_server/cron.go b/internal/web_server/cron.go index 56565af..632c6e3 100644 --- a/internal/web_server/cron.go +++ b/internal/web_server/cron.go @@ -24,22 +24,22 @@ func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.S spec string task func() }{ - // { - // spec: "0 0 * * * *", // Every 1 hour - // task: func() { - // if err := eventService.FetchUpcomingEvents(context.Background()); err != nil { - // log.Printf("FetchUpcomingEvents error: %v", err) - // } - // }, - // }, - // { - // spec: "0 0 * * * *", // Every 1 hour (since its takes that long to fetch all the events) - // task: func() { - // if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil { - // log.Printf("FetchNonLiveOdds error: %v", err) - // } - // }, - // }, + { + spec: "0 0 * * * *", // Every 1 hour + task: func() { + if err := eventService.FetchUpcomingEvents(context.Background()); err != nil { + log.Printf("FetchUpcomingEvents error: %v", err) + } + }, + }, + { + spec: "0 0 * * * *", // Every 1 hour (since its takes that long to fetch all the events) + task: func() { + if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil { + log.Printf("FetchNonLiveOdds error: %v", err) + } + }, + }, { spec: "0 */5 * * * *", // Every 5 Minutes task: func() { diff --git a/internal/web_server/handlers/branch_handler.go b/internal/web_server/handlers/branch_handler.go index d085a38..f73c20d 100644 --- a/internal/web_server/handlers/branch_handler.go +++ b/internal/web_server/handlers/branch_handler.go @@ -99,12 +99,13 @@ func (h *Handler) CreateBranch(c *fiber.Ctx) error { } branch, err := h.branchSvc.CreateBranch(c.Context(), domain.CreateBranch{ - Name: req.Name, - Location: req.Location, - WalletID: newWallet.ID, - BranchManagerID: req.BranchManagerID, - CompanyID: checkedCompanyID, - IsSelfOwned: IsSelfOwned, + Name: req.Name, + Location: req.Location, + WalletID: newWallet.ID, + BranchManagerID: req.BranchManagerID, + CompanyID: checkedCompanyID, + IsSelfOwned: IsSelfOwned, + ProfitPercentage: req.ProfitPercentage, }) if err != nil { @@ -619,7 +620,6 @@ func (h *Handler) GetBranchOperations(c *fiber.Ctx) error { return response.WriteJSON(c, fiber.StatusOK, "Branch Operations retrieved successfully", result, nil) } - // GetAllBranchLocations godoc // @Summary Gets all branch locations // @Description Gets all branch locations diff --git a/internal/web_server/handlers/company_handler.go b/internal/web_server/handlers/company_handler.go index d7c8551..8eb731c 100644 --- a/internal/web_server/handlers/company_handler.go +++ b/internal/web_server/handlers/company_handler.go @@ -50,6 +50,7 @@ func (h *Handler) CreateCompany(c *fiber.Ctx) error { user, err := h.userSvc.GetUserByID(c.Context(), req.AdminID) if err != nil { h.mongoLoggerSvc.Error("Error fetching user", + zap.Int("admin_id", int(req.AdminID)), zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), zap.Time("timestamp", time.Now()), @@ -76,9 +77,10 @@ func (h *Handler) CreateCompany(c *fiber.Ctx) error { } company, err := h.companySvc.CreateCompany(c.Context(), domain.CreateCompany{ - Name: req.Name, - AdminID: user.ID, - WalletID: newWallet.ID, + Name: req.Name, + AdminID: user.ID, + WalletID: newWallet.ID, + DeductedPercentage: req.DeductedPercentage, }) if err != nil { diff --git a/internal/web_server/handlers/issue_reporting.go b/internal/web_server/handlers/issue_reporting.go index 8cc45c9..0dd334e 100644 --- a/internal/web_server/handlers/issue_reporting.go +++ b/internal/web_server/handlers/issue_reporting.go @@ -115,7 +115,23 @@ func (h *Handler) GetAllIssues(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusInternalServerError, "Failed to get all issues:"+err.Error()) } - return c.JSON(issues) + results := make([]domain.ReportedIssue, len(issues)) + for i, issue := range issues { + results[i] = domain.ReportedIssue{ + ID: issue.ID, + UserID: issue.UserID, + UserRole: domain.Role(issue.UserRole), + Subject: issue.Subject, + Description: issue.Description, + IssueType: domain.ReportedIssueType(issue.IssueType), + Status: domain.ReportedIssueStatus(issue.Status), + // Metadata: issue.Metadata, + CreatedAt: issue.CreatedAt.Time, + UpdatedAt: issue.UpdatedAt.Time, + } + } + + return c.JSON(results) } // UpdateIssueStatus godoc diff --git a/internal/web_server/handlers/leagues.go b/internal/web_server/handlers/leagues.go index 794bac2..09b63a1 100644 --- a/internal/web_server/handlers/leagues.go +++ b/internal/web_server/handlers/leagues.go @@ -140,7 +140,7 @@ func (h *Handler) SetLeagueActive(c *fiber.Ctx) error { if err := h.leagueSvc.SetLeagueActive(c.Context(), int64(leagueId), req.IsActive); err != nil { h.mongoLoggerSvc.Error("Failed to update league active", - zap.Int64("userID", int64(leagueId)), + zap.Int64("leagueID", int64(leagueId)), zap.Bool("is_active", req.IsActive), zap.Int("status_code", fiber.StatusInternalServerError), zap.Error(err), @@ -149,6 +149,14 @@ func (h *Handler) SetLeagueActive(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusInternalServerError, "Failed to update league:"+err.Error()) } + h.mongoLoggerSvc.Info("League Active has been successfully updated", + zap.Int64("userID", int64(leagueId)), + zap.Int64("leagueID", int64(leagueId)), + zap.Bool("is_active", req.IsActive), + zap.Int("status_code", fiber.StatusOK), + zap.Time("timestamp", time.Now()), + ) + return response.WriteJSON(c, fiber.StatusOK, "League updated successfully", nil, nil) } @@ -206,6 +214,10 @@ func (h *Handler) SetLeagueFeatured(c *fiber.Ctx) error { } err = h.leagueSvc.UpdateLeague(c.Context(), domain.UpdateLeague{ ID: int64(leagueId), + IsFeatured: domain.ValidBool{ + Value: req.IsFeatured, + Valid: true, + }, }) if err != nil { h.mongoLoggerSvc.Error("Failed to update league", @@ -216,6 +228,12 @@ func (h *Handler) SetLeagueFeatured(c *fiber.Ctx) error { ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to update league:"+err.Error()) } - + h.mongoLoggerSvc.Info("League Featured has been successfully updated", + zap.Int64("userID", int64(leagueId)), + zap.Int64("leagueID", int64(leagueId)), + zap.Bool("is_featured", req.IsFeatured), + zap.Int("status_code", fiber.StatusOK), + zap.Time("timestamp", time.Now()), + ) return response.WriteJSON(c, fiber.StatusOK, "League updated successfully", nil, nil) } diff --git a/internal/web_server/handlers/mongoLogger.go b/internal/web_server/handlers/mongoLogger.go index 2ccc7a2..6655ae3 100644 --- a/internal/web_server/handlers/mongoLogger.go +++ b/internal/web_server/handlers/mongoLogger.go @@ -99,7 +99,7 @@ func GetLogsHandler(appCtx context.Context) fiber.Handler { } defer cursor.Close(appCtx) - var logs []domain.LogEntry + var logs []domain.LogEntry = make([]domain.LogEntry, 0) if err := cursor.All(appCtx, &logs); err != nil { return fiber.NewError(fiber.StatusInternalServerError, "Cursor decoding error: "+err.Error()) } @@ -113,7 +113,7 @@ func GetLogsHandler(appCtx context.Context) fiber.Handler { // Prepare response response := domain.LogResponse{ Message: "Logs fetched successfully", - Data: logs, + Data: logs, Pagination: domain.Pagination{ Total: int(total), TotalPages: totalPages, diff --git a/internal/web_server/handlers/notification_handler.go b/internal/web_server/handlers/notification_handler.go index 4a5e106..e278581 100644 --- a/internal/web_server/handlers/notification_handler.go +++ b/internal/web_server/handlers/notification_handler.go @@ -117,7 +117,7 @@ func (h *Handler) ConnectSocket(c *fiber.Ctx) error { zap.Time("timestamp", time.Now()), ) } else { - h.mongoLoggerSvc.Warn("Unexpected WebSocket closure", + h.mongoLoggerSvc.Info("Unexpected WebSocket closure", zap.Int64("userID", userID), zap.Int("status_code", fiber.StatusBadRequest), zap.Error(err), diff --git a/internal/web_server/handlers/report.go b/internal/web_server/handlers/report.go index a34b8e5..63308da 100644 --- a/internal/web_server/handlers/report.go +++ b/internal/web_server/handlers/report.go @@ -35,11 +35,13 @@ import ( // @Failure 500 {object} domain.ErrorResponse // @Router /api/v1/reports/dashboard [get] func (h *Handler) GetDashboardReport(c *fiber.Ctx) error { + role := c.Locals("role").(domain.Role) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // Parse query parameters - filter, err := parseReportFilter(c) + filter, err := parseReportFilter(c, role) if err != nil { return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{ Message: "Invalid filter parameters", @@ -70,10 +72,9 @@ func (h *Handler) GetDashboardReport(c *fiber.Ctx) error { } // parseReportFilter parses query parameters into ReportFilter -func parseReportFilter(c *fiber.Ctx) (domain.ReportFilter, error) { +func parseReportFilter(c *fiber.Ctx, role domain.Role) (domain.ReportFilter, error) { var filter domain.ReportFilter var err error - role := c.Locals("role").(domain.Role) if c.Query("company_id") != "" && role == domain.RoleSuperAdmin { diff --git a/internal/web_server/routes.go b/internal/web_server/routes.go index acb6a45..4b37043 100644 --- a/internal/web_server/routes.go +++ b/internal/web_server/routes.go @@ -55,7 +55,7 @@ func (a *App) initAppRoutes() { a.fiber.Get("/", func(c *fiber.Ctx) error { return c.JSON(fiber.Map{ "message": "Welcome to the FortuneBet API", - "version": "1.0dev10", + "version": "1.0dev11", }) }) // Swagger @@ -65,7 +65,7 @@ func (a *App) initAppRoutes() { groupV1.Get("/", func(c *fiber.Ctx) error { return c.JSON(fiber.Map{ "message": "FortuneBet API V1 pre-alpha", - "version": "1.0dev10", + "version": "1.0dev11", }) }) // Auth Routes @@ -241,7 +241,7 @@ func (a *App) initAppRoutes() { groupV1.Get("/currencies/convert", h.ConvertCurrency) //Report Routes - groupV1.Get("/reports/dashboard", h.GetDashboardReport) + groupV1.Get("/reports/dashboard", a.authMiddleware, a.OnlyAdminAndAbove, h.GetDashboardReport) groupV1.Get("/report-files/download/:filename", a.authMiddleware, a.OnlyAdminAndAbove, h.DownloadReportFile) groupV1.Get("/report-files/list", a.authMiddleware, a.OnlyAdminAndAbove, h.ListReportFiles)