Merge pull request 'Enhance notification search functionality and update API documentation' (#40) from TM-616 into develop
Reviewed-on: https://repo.ravanertebat.com/TM/tm_back/pulls/40 Reviewed-by: Hadi Barzegar <barzagarhadi@gmail.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package notification
|
package notification
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"tm/pkg/response"
|
"tm/pkg/response"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,6 +23,8 @@ type NotificationRequest struct {
|
|||||||
|
|
||||||
// SearchForm represents the form for searching notifications
|
// SearchForm represents the form for searching notifications
|
||||||
type SearchForm struct {
|
type SearchForm struct {
|
||||||
|
Q *string `query:"q" valid:"optional"`
|
||||||
|
Search *string `query:"search" valid:"optional"`
|
||||||
Status string `query:"status" valid:"optional"`
|
Status string `query:"status" valid:"optional"`
|
||||||
Method string `query:"method" valid:"optional"`
|
Method string `query:"method" valid:"optional"`
|
||||||
EventType string `query:"event_type" valid:"optional"`
|
EventType string `query:"event_type" valid:"optional"`
|
||||||
@@ -30,6 +34,17 @@ type SearchForm struct {
|
|||||||
Priority string `query:"priority" valid:"optional"`
|
Priority string `query:"priority" valid:"optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResolvedSearch returns the search term from either the search or q query parameter.
|
||||||
|
func (f *SearchForm) ResolvedSearch() string {
|
||||||
|
if f.Search != nil && strings.TrimSpace(*f.Search) != "" {
|
||||||
|
return strings.TrimSpace(*f.Search)
|
||||||
|
}
|
||||||
|
if f.Q != nil {
|
||||||
|
return strings.TrimSpace(*f.Q)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type NotificationListResponse struct {
|
type NotificationListResponse struct {
|
||||||
Notifications []*NotificationResponse `json:"notifications"`
|
Notifications []*NotificationResponse `json:"notifications"`
|
||||||
Meta *response.Meta `json:"meta"`
|
Meta *response.Meta `json:"meta"`
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ func (h *NotificationHandler) Send(c echo.Context) error {
|
|||||||
// @Tags Admin-Notification
|
// @Tags Admin-Notification
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
|
// @Param search query string false "Search query for title and message"
|
||||||
|
// @Param q query string false "Search query for title and message (alias of search)"
|
||||||
// @Param status query string false "Status filter"
|
// @Param status query string false "Status filter"
|
||||||
// @Param method query string false "Method filter"
|
// @Param method query string false "Method filter"
|
||||||
// @Param event_type query string false "Event type filter"
|
// @Param event_type query string false "Event type filter"
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package notification
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tm/pkg/logger"
|
"tm/pkg/logger"
|
||||||
@@ -52,7 +54,7 @@ func (n *Notification) GetID() string {
|
|||||||
type Repository interface {
|
type Repository interface {
|
||||||
Create(ctx context.Context, notification *Notification) error
|
Create(ctx context.Context, notification *Notification) error
|
||||||
GetByID(ctx context.Context, id string) (*Notification, error)
|
GetByID(ctx context.Context, id string) (*Notification, error)
|
||||||
GetByUserID(ctx context.Context, userIDs []string, status string, seen *bool, priority, eventType, notificationType string, pagination *response.Pagination) (*orm.PaginatedResult[Notification], error)
|
GetByUserID(ctx context.Context, userIDs []string, search, status string, seen *bool, priority, eventType, notificationType string, pagination *response.Pagination) (*orm.PaginatedResult[Notification], error)
|
||||||
Update(ctx context.Context, notification *Notification) error
|
Update(ctx context.Context, notification *Notification) error
|
||||||
MarkAsSeen(ctx context.Context, notificationID, userID string) error
|
MarkAsSeen(ctx context.Context, notificationID, userID string) error
|
||||||
MarkAllAsSeen(ctx context.Context, userID string) error
|
MarkAllAsSeen(ctx context.Context, userID string) error
|
||||||
@@ -115,9 +117,17 @@ func (r *notificationRepository) GetByID(ctx context.Context, id string) (*Notif
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetByUserID retrieves notifications with optional user filters
|
// GetByUserID retrieves notifications with optional user filters
|
||||||
func (r *notificationRepository) GetByUserID(ctx context.Context, userIDs []string, status string, seen *bool, priority, eventType, notificationType string, pagination *response.Pagination) (*orm.PaginatedResult[Notification], error) {
|
func (r *notificationRepository) GetByUserID(ctx context.Context, userIDs []string, search, status string, seen *bool, priority, eventType, notificationType string, pagination *response.Pagination) (*orm.PaginatedResult[Notification], error) {
|
||||||
filter := bson.M{}
|
filter := bson.M{}
|
||||||
|
|
||||||
|
if q := strings.TrimSpace(search); q != "" {
|
||||||
|
pattern := regexp.QuoteMeta(q)
|
||||||
|
filter["$or"] = bson.A{
|
||||||
|
bson.M{"title": bson.M{"$regex": pattern, "$options": "i"}},
|
||||||
|
bson.M{"message": bson.M{"$regex": pattern, "$options": "i"}},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(userIDs) == 1 {
|
if len(userIDs) == 1 {
|
||||||
filter["user_id"] = userIDs[0]
|
filter["user_id"] = userIDs[0]
|
||||||
} else if len(userIDs) > 1 {
|
} else if len(userIDs) > 1 {
|
||||||
|
|||||||
@@ -183,7 +183,10 @@ func (s *notificationService) persistNotification(ctx context.Context, recipient
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *notificationService) GetNotifications(ctx context.Context, req *SearchForm, pagination *response.Pagination) (*NotificationListResponse, error) {
|
func (s *notificationService) GetNotifications(ctx context.Context, req *SearchForm, pagination *response.Pagination) (*NotificationListResponse, error) {
|
||||||
|
search := req.ResolvedSearch()
|
||||||
|
|
||||||
s.logger.Info("Getting notifications", map[string]interface{}{
|
s.logger.Info("Getting notifications", map[string]interface{}{
|
||||||
|
"search": search,
|
||||||
"status": req.Status,
|
"status": req.Status,
|
||||||
"method": req.Method,
|
"method": req.Method,
|
||||||
"event_type": req.EventType,
|
"event_type": req.EventType,
|
||||||
@@ -195,7 +198,7 @@ func (s *notificationService) GetNotifications(ctx context.Context, req *SearchF
|
|||||||
"offset": pagination.Offset,
|
"offset": pagination.Offset,
|
||||||
})
|
})
|
||||||
|
|
||||||
page, 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, search, req.Status, req.Seen, req.Priority, req.EventType, req.Type, pagination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to get notifications", map[string]interface{}{
|
s.logger.Error("Failed to get notifications", map[string]interface{}{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
|
|||||||
Reference in New Issue
Block a user