Files
Novault-backend/internal/handler/notification_handler.go

159 lines
4.2 KiB
Go

package handler
import (
"accounting-app/internal/models"
"accounting-app/internal/service"
"accounting-app/pkg/api"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
type NotificationHandler struct {
service *service.NotificationService
}
func NewNotificationHandler(service *service.NotificationService) *NotificationHandler {
return &NotificationHandler{service: service}
}
// GetNotifications returns a list of notifications for the user
func (h *NotificationHandler) GetNotifications(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
api.Unauthorized(c, "User not authenticated")
return
}
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
var isRead *bool
if val, ok := c.GetQuery("is_read"); ok {
parsedVal, err := strconv.ParseBool(val)
if err == nil {
isRead = &parsedVal
}
}
notifications, total, err := h.service.GetNotifications(userID.(uint), page, limit, isRead)
if err != nil {
api.Error(c, http.StatusInternalServerError, "FETCH_ERROR", "Failed to fetch notifications")
return
}
api.Success(c, gin.H{
"notifications": notifications,
"total": total,
"page": page,
"limit": limit,
})
}
// GetUnreadCount returns the number of unread notifications
func (h *NotificationHandler) GetUnreadCount(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
api.Unauthorized(c, "User not authenticated")
return
}
count, err := h.service.GetUnreadCount(userID.(uint))
if err != nil {
api.Error(c, http.StatusInternalServerError, "FETCH_ERROR", "Failed to count unread notifications")
return
}
api.Success(c, gin.H{
"count": count,
})
}
// MarkAsRead marks a specific notification as read
func (h *NotificationHandler) MarkAsRead(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
api.Unauthorized(c, "User not authenticated")
return
}
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
api.Error(c, http.StatusBadRequest, "INVALID_ID", "Invalid notification ID")
return
}
if err := h.service.MarkAsRead(uint(id), userID.(uint)); err != nil {
api.Error(c, http.StatusInternalServerError, "UPDATE_ERROR", "Failed to mark as read")
return
}
api.Success(c, gin.H{"message": "Marked as read"})
}
// MarkAllAsRead marks all notifications as read
func (h *NotificationHandler) MarkAllAsRead(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
api.Unauthorized(c, "User not authenticated")
return
}
if err := h.service.MarkAllAsRead(userID.(uint)); err != nil {
api.Error(c, http.StatusInternalServerError, "UPDATE_ERROR", "Failed to mark all as read")
return
}
api.Success(c, gin.H{"message": "All marked as read"})
}
// CreateNotificationRequest represents the request body for creating a notification (internal/admin use primarily)
type CreateNotificationRequest struct {
Title string `json:"title" binding:"required"`
Content string `json:"content" binding:"required"`
Type string `json:"type" binding:"required"`
Link string `json:"link"`
}
// CreateNotification creates a new notification (For testing/admin purposes)
func (h *NotificationHandler) CreateNotification(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
api.Unauthorized(c, "User not authenticated")
return
}
var req CreateNotificationRequest
if err := c.ShouldBindJSON(&req); err != nil {
api.Error(c, http.StatusBadRequest, "INVALID_REQUEST", "Invalid request")
return
}
err := h.service.CreateNotification(
userID.(uint),
req.Title,
req.Content,
models.NotificationType(req.Type),
req.Link,
)
if err != nil {
api.Error(c, http.StatusInternalServerError, "CREATE_ERROR", "Failed to create notification")
return
}
api.Success(c, gin.H{"message": "Notification created"})
}
// RegisterRoutes registers the notification routes
func (h *NotificationHandler) RegisterRoutes(r *gin.RouterGroup) {
notifications := r.Group("/notifications")
{
notifications.GET("", h.GetNotifications)
notifications.GET("/unread-count", h.GetUnreadCount)
notifications.PUT("/:id/read", h.MarkAsRead)
notifications.PUT("/read-all", h.MarkAllAsRead)
notifications.POST("", h.CreateNotification) // Admin/Internal use
}
}