hybrid pagination
This commit is contained in:
@@ -87,11 +87,16 @@ func (h *NotificationHandler) GetNotifications(c echo.Context) error {
|
||||
return response.ValidationError(c, err.Error(), "")
|
||||
}
|
||||
|
||||
pagination := response.NewPagination(c)
|
||||
pagination, err := response.NewPagination(c)
|
||||
if err != nil {
|
||||
return response.PaginationBadRequest(c, err)
|
||||
}
|
||||
|
||||
// Call service
|
||||
notifications, err := h.service.GetNotifications(c.Request().Context(), form, pagination)
|
||||
if err != nil {
|
||||
if response.IsListPaginationError(err) {
|
||||
return response.PaginationBadRequest(c, err)
|
||||
}
|
||||
return response.InternalServerError(c, "Failed to get notifications")
|
||||
}
|
||||
|
||||
@@ -141,11 +146,16 @@ func (h *NotificationHandler) AdminNotifications(c echo.Context) error {
|
||||
form.Recipient = userID
|
||||
form.Status = "sent"
|
||||
|
||||
pagination := response.NewPagination(c)
|
||||
pagination, err := response.NewPagination(c)
|
||||
if err != nil {
|
||||
return response.PaginationBadRequest(c, err)
|
||||
}
|
||||
|
||||
// Call service
|
||||
notifications, err := h.service.GetNotifications(c.Request().Context(), form, pagination)
|
||||
if err != nil {
|
||||
if response.IsListPaginationError(err) {
|
||||
return response.PaginationBadRequest(c, err)
|
||||
}
|
||||
return response.InternalServerError(c, "Failed to get notifications")
|
||||
}
|
||||
|
||||
@@ -254,12 +264,16 @@ func (h *NotificationHandler) CustomerNotifications(c echo.Context) error {
|
||||
form.Recipient = userID
|
||||
form.Status = "sent"
|
||||
|
||||
pagination := response.NewPagination(c)
|
||||
pagination, err := response.NewPagination(c)
|
||||
if err != nil {
|
||||
return response.PaginationBadRequest(c, err)
|
||||
}
|
||||
|
||||
// Call service
|
||||
notifications, err := h.service.GetNotifications(c.Request().Context(), form, pagination)
|
||||
if err != nil {
|
||||
// Log the actual error for debugging
|
||||
if response.IsListPaginationError(err) {
|
||||
return response.PaginationBadRequest(c, err)
|
||||
}
|
||||
c.Logger().Error("GetNotifications failed", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"status": form.Status,
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
mongopkg "go.mongodb.org/mongo-driver/v2/mongo"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -45,7 +44,7 @@ type Notification struct {
|
||||
type Repository interface {
|
||||
Create(ctx context.Context, notification *Notification) error
|
||||
GetByID(ctx context.Context, id string) (*Notification, error)
|
||||
GetByUserID(ctx context.Context, userID string, status string, seen *bool, priority, eventType, notificationType string, pagination *response.Pagination) ([]Notification, int64, error)
|
||||
GetByUserID(ctx context.Context, userID string, status string, seen *bool, priority, eventType, notificationType string, pagination *response.Pagination) (*orm.PaginatedResult[Notification], error)
|
||||
Update(ctx context.Context, notification *Notification) error
|
||||
MarkAsSeen(ctx context.Context, notificationID, userID string) error
|
||||
MarkAllAsSeen(ctx context.Context, userID string) error
|
||||
@@ -108,7 +107,7 @@ func (r *notificationRepository) GetByID(ctx context.Context, id string) (*Notif
|
||||
}
|
||||
|
||||
// GetByUserID retrieves notifications for a specific user with filters
|
||||
func (r *notificationRepository) GetByUserID(ctx context.Context, userID string, status string, seen *bool, priority, eventType, notificationType string, pagination *response.Pagination) ([]Notification, int64, error) {
|
||||
func (r *notificationRepository) GetByUserID(ctx context.Context, userID string, status string, seen *bool, priority, eventType, notificationType string, pagination *response.Pagination) (*orm.PaginatedResult[Notification], error) {
|
||||
filter := bson.M{"user_id": userID}
|
||||
|
||||
if status != "" {
|
||||
@@ -131,48 +130,29 @@ func (r *notificationRepository) GetByUserID(ctx context.Context, userID string,
|
||||
filter["type"] = notificationType
|
||||
}
|
||||
|
||||
// Get total count
|
||||
total, err := r.collection.CountDocuments(ctx, filter)
|
||||
mongoPagination, err := orm.BuildListPagination(
|
||||
pagination.Limit,
|
||||
pagination.Offset,
|
||||
pagination.Cursor,
|
||||
pagination.SortBy,
|
||||
pagination.SortOrder,
|
||||
filter,
|
||||
orm.ListPaginationOptions{},
|
||||
)
|
||||
if err != nil {
|
||||
r.logger.Error("Failed to count notifications", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"user_id": userID,
|
||||
})
|
||||
return nil, 0, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Build find options
|
||||
findOptions := options.Find()
|
||||
if pagination.Limit > 0 {
|
||||
findOptions.SetLimit(int64(pagination.Limit))
|
||||
}
|
||||
if pagination.Offset > 0 {
|
||||
findOptions.SetSkip(int64(pagination.Offset))
|
||||
}
|
||||
|
||||
// Sort by created_at descending
|
||||
findOptions.SetSort(bson.D{{Key: "created_at", Value: -1}})
|
||||
|
||||
cursor, err := r.collection.Find(ctx, filter, findOptions)
|
||||
result, err := r.ormRepo.FindAll(ctx, filter, mongoPagination)
|
||||
if err != nil {
|
||||
r.logger.Error("Failed to find notifications", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"user_id": userID,
|
||||
})
|
||||
return nil, 0, err
|
||||
}
|
||||
defer cursor.Close(ctx)
|
||||
|
||||
var notifications []Notification
|
||||
if err := cursor.All(ctx, ¬ifications); err != nil {
|
||||
r.logger.Error("Failed to decode notifications", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"user_id": userID,
|
||||
})
|
||||
return nil, 0, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return notifications, total, nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Update updates a notification
|
||||
|
||||
@@ -194,7 +194,7 @@ func (s *notificationService) GetNotifications(ctx context.Context, req *SearchF
|
||||
"offset": pagination.Offset,
|
||||
})
|
||||
|
||||
notifications, total, err := s.repository.GetByUserID(ctx, req.Recipient, req.Status, req.Seen, req.Priority, req.EventType, req.Type, pagination)
|
||||
page, err := s.repository.GetByUserID(ctx, req.Recipient, req.Status, req.Seen, req.Priority, req.EventType, req.Type, pagination)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to get notifications", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
@@ -203,7 +203,7 @@ func (s *notificationService) GetNotifications(ctx context.Context, req *SearchF
|
||||
}
|
||||
|
||||
notificationsResponse := make([]*NotificationResponse, 0)
|
||||
for _, notification := range notifications {
|
||||
for _, notification := range page.Items {
|
||||
usr, _ := s.userService.GetUserByID(ctx, notification.UserID)
|
||||
cust, _ := s.customerService.GetByID(ctx, notification.UserID)
|
||||
|
||||
@@ -250,21 +250,9 @@ func (s *notificationService) GetNotifications(ctx context.Context, req *SearchF
|
||||
})
|
||||
}
|
||||
|
||||
// Calculate total pages
|
||||
totalPages := int(total) / pagination.Limit
|
||||
if int(total)%pagination.Limit > 0 {
|
||||
totalPages++
|
||||
}
|
||||
|
||||
return &NotificationListResponse{
|
||||
Notifications: notificationsResponse,
|
||||
Meta: &response.Meta{
|
||||
Total: int(total),
|
||||
Limit: pagination.Limit,
|
||||
Offset: pagination.Offset,
|
||||
Page: (pagination.Offset / pagination.Limit) + 1,
|
||||
Pages: totalPages,
|
||||
},
|
||||
Meta: pagination.ListMeta(page.TotalCount, page.NextCursor, page.HasMore, page.PageOffset),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user