From 4a2ae14a64c5a044f8aac2db24a16a660b631993 Mon Sep 17 00:00:00 2001 From: KidusAlemayehu Date: Tue, 13 May 2025 22:43:51 +0300 Subject: [PATCH] add notification retrieval endpoint; refactor middleware for company role validation --- docker-compose.yml | 9 ++- .../handlers/notification_handler.go | 55 ++++++++++++++++--- internal/web_server/middleware.go | 2 +- internal/web_server/routes.go | 1 + 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 4bbf5e6..e1f077d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.9' - services: postgres: image: postgres:16-alpine @@ -16,6 +14,8 @@ services: interval: 5s timeout: 3s retries: 5 + volumes: + - postgres_data:/var/lib/postgresql/data migrate: image: migrate/migrate @@ -65,4 +65,7 @@ services: networks: app: - driver: bridge \ No newline at end of file + driver: bridge + +volumes: + postgres_data: diff --git a/internal/web_server/handlers/notification_handler.go b/internal/web_server/handlers/notification_handler.go index 8c6337b..3d61451 100644 --- a/internal/web_server/handlers/notification_handler.go +++ b/internal/web_server/handlers/notification_handler.go @@ -5,6 +5,7 @@ import ( "encoding/json" "net" "net/http" + "strconv" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/ws" @@ -143,18 +144,18 @@ func (h *Handler) CreateAndSendNotification(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusBadRequest, "Invalid request body") } - userID, ok := c.Locals("userID").(int64) - if !ok || userID == 0 { - h.logger.Error("[NotificationSvc.CreateAndSendNotification] Invalid user ID in context") - return fiber.NewError(fiber.StatusUnauthorized, "Invalid user identification") - } + // userID, ok := c.Locals("userID").(int64) + // if !ok || userID == 0 { + // h.logger.Error("[NotificationSvc.CreateAndSendNotification] Invalid user ID in context") + // return fiber.NewError(fiber.StatusUnauthorized, "Invalid user identification") + // } switch req.DeliveryScheme { case domain.NotificationDeliverySchemeSingle: - if req.Reciever == domain.NotificationRecieverSideCustomer && req.RecipientID != userID { - h.logger.Warn("[NotificationSvc.CreateAndSendNotification] Unauthorized attempt to send notification", "userID", userID, "recipientID", req.RecipientID) - return fiber.NewError(fiber.StatusForbidden, "Unauthorized to send notification to this recipient") - } + // if req.Reciever == domain.NotificationRecieverSideCustomer { + // h.logger.Warn("[NotificationSvc.CreateAndSendNotification] Unauthorized attempt to send notification", "recipientID", req.RecipientID) + // return fiber.NewError(fiber.StatusForbidden, "Unauthorized to send notification to this recipient") + // } notification := &domain.Notification{ ID: "", @@ -223,6 +224,42 @@ func (h *Handler) CreateAndSendNotification(c *fiber.Ctx) error { } } +func (h *Handler) GetNotifications(c *fiber.Ctx) error { + limitStr := c.Query("limit", "10") + offsetStr := c.Query("offset", "0") + + // Convert limit and offset to integers + limit, err := strconv.Atoi(limitStr) + if err != nil || limit <= 0 { + h.logger.Error("[NotificationSvc.GetNotifications] Invalid limit value", "error", err) + return fiber.NewError(fiber.StatusBadRequest, "Invalid limit value") + } + offset, err := strconv.Atoi(offsetStr) + if err != nil || offset < 0 { + h.logger.Error("[NotificationSvc.GetNotifications] Invalid offset value", "error", err) + return fiber.NewError(fiber.StatusBadRequest, "Invalid offset value") + } + + userID, ok := c.Locals("user_id").(int64) + if !ok || userID == 0 { + h.logger.Error("[NotificationSvc.GetNotifications] Invalid user ID in context") + return fiber.NewError(fiber.StatusUnauthorized, "Invalid user identification") + } + + notifications, err := h.notificationSvc.ListNotifications(context.Background(), userID, limit, offset) + if err != nil { + h.logger.Error("[NotificationSvc.GetNotifications] Failed to fetch notifications", "error", err) + return fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch notifications") + } + + return c.Status(fiber.StatusOK).JSON(fiber.Map{ + "notifications": notifications, + "total_count": len(notifications), + "limit": limit, + "offset": offset, + }) +} + func (h *Handler) getAllRecipientIDs(ctx context.Context, receiver domain.NotificationRecieverSide) ([]int64, error) { return h.notificationSvc.ListRecipientIDs(ctx, receiver) } diff --git a/internal/web_server/middleware.go b/internal/web_server/middleware.go index 63cfe6e..8e550cb 100644 --- a/internal/web_server/middleware.go +++ b/internal/web_server/middleware.go @@ -44,7 +44,7 @@ func (a *App) authMiddleware(c *fiber.Ctx) error { } // Asserting to make sure that there is no company role without a valid company id - if claim.Role != domain.RoleSuperAdmin && !claim.CompanyID.Valid { + if claim.Role != domain.RoleSuperAdmin && claim.Role != domain.RoleCustomer && !claim.CompanyID.Valid { fmt.Println("Company Role without Company ID") return fiber.NewError(fiber.StatusInternalServerError, "Company Role without Company ID") } diff --git a/internal/web_server/routes.go b/internal/web_server/routes.go index 6095931..70fb79a 100644 --- a/internal/web_server/routes.go +++ b/internal/web_server/routes.go @@ -170,6 +170,7 @@ func (a *App) initAppRoutes() { // Notification Routes a.fiber.Get("/ws/connect", a.WebsocketAuthMiddleware, h.ConnectSocket) + a.fiber.Get("/notifications", a.authMiddleware, h.GetNotifications) a.fiber.Post("/notifications/mark-as-read", h.MarkNotificationAsRead) a.fiber.Post("/notifications/create", h.CreateAndSendNotification)