Files
tm_back/pkg/notification/entities.go
T
n.nakhostin aef91b4711 Add Notification Filters for Seen and Priority
- Introduced new optional fields in the SearchForm for filtering notifications by 'seen' status and 'priority', enhancing the flexibility of notification retrieval.
- Updated the GetNotifications method in the notification service to accommodate the new filters, ensuring they are included in the query parameters.
- Enhanced the notification client to support the new filters in API requests, improving the overall functionality of the notification system.
- Updated API documentation with Swagger comments to reflect the new query parameters, ensuring clarity for API consumers.
2025-09-22 09:57:14 +03:30

205 lines
7.0 KiB
Go

package notification
import (
"time"
"github.com/asaskevich/govalidator"
)
// EventType represents the type of notification event
type EventType string
const (
EventTypeEmail EventType = "EMAIL"
EventTypeSMS EventType = "SMS"
EventTypePush EventType = "PUSH"
EventTypeOTP EventType = "OTP"
)
// NotificationMethods contains different delivery methods for notifications
type NotificationMethods struct {
OTP string `json:"otp,omitempty" valid:"optional"`
SMS string `json:"sms,omitempty" valid:"optional"`
Push string `json:"push,omitempty" valid:"optional"`
Email string `json:"email,omitempty" valid:"optional,email"`
}
// NotificationRequest represents the request structure for sending notifications
type NotificationRequest struct {
UserID string `json:"user_id"`
Title string `json:"title"`
Message string `json:"message"`
Type string `json:"type"`
EventType EventType `json:"event_type"`
Priority string `json:"priority"`
ScheduledAt int64 `json:"scheduled_at"`
Metadata map[string]any `json:"metadata"`
Methods NotificationMethods `json:"methods"`
}
// NotificationResponse represents the successful response from notification service
type NotificationResponse struct {
Status string `json:"status"`
}
// DetailedNotificationResponse represents a detailed notification response
type DetailedNotificationResponse struct {
Data struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Title string `json:"title"`
Message string `json:"message"`
Link string `json:"link"`
Image string `json:"image"`
Type string `json:"type"` // info, warning, alert, reject
Priority string `json:"priority"` // low, medium, important
EventType string `json:"event_type"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Methods map[string]string `json:"methods"`
Metadata map[string]any `json:"metadata"`
Status string `json:"status"` // pending, sent, failed
Seen bool `json:"seen"`
SeenAt int64 `json:"seen_at"`
ScheduledAt int64 `json:"scheduled_at"`
IsScheduled bool `json:"is_scheduled"`
} `json:"data"`
}
// NotificationErrorResponse represents the error response from notification service
type NotificationErrorResponse struct {
Error string `json:"error"`
}
// Validate validates the notification request
func (nr *NotificationRequest) Validate() error {
// First run govalidator validation
if _, err := govalidator.ValidateStruct(nr); err != nil {
return ErrValidation{Field: "struct", Message: err.Error()}
}
// Custom validation: ensure at least one method is provided based on event type
switch nr.EventType {
case EventTypeEmail:
if nr.Methods.Email == "" {
return ErrValidation{Field: "methods.email", Message: "email address is required for EMAIL event type"}
}
case EventTypeSMS:
if nr.Methods.SMS == "" {
return ErrValidation{Field: "methods.sms", Message: "SMS number is required for SMS event type"}
}
case EventTypePush:
if nr.Methods.Push == "" {
return ErrValidation{Field: "methods.push", Message: "push device token is required for PUSH event type"}
}
case EventTypeOTP:
if nr.Methods.OTP == "" {
return ErrValidation{Field: "methods.otp", Message: "OTP number is required for OTP event type"}
}
}
// Validate scheduled_at: 0 means immediate delivery, otherwise must be future timestamp
if nr.ScheduledAt < 0 {
return ErrValidation{Field: "scheduled_at", Message: "scheduled_at cannot be negative"}
}
return nil
}
// HasMethod checks if a specific method is configured
func (nm *NotificationMethods) HasMethod(eventType EventType) bool {
switch eventType {
case EventTypeEmail:
return nm.Email != ""
case EventTypeSMS:
return nm.SMS != ""
case EventTypePush:
return nm.Push != ""
case EventTypeOTP:
return nm.OTP != ""
default:
return false
}
}
// GetMethodValue returns the value for a specific method
func (nm *NotificationMethods) GetMethodValue(eventType EventType) string {
switch eventType {
case EventTypeEmail:
return nm.Email
case EventTypeSMS:
return nm.SMS
case EventTypePush:
return nm.Push
case EventTypeOTP:
return nm.OTP
default:
return ""
}
}
// IsImmediate returns true if the notification should be sent immediately (scheduled_at = 0)
func (nr *NotificationRequest) IsImmediate() bool {
return nr.ScheduledAt == 0
}
// NotificationItem represents a single notification in the list response
type NotificationItem struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Title string `json:"title"`
Message string `json:"message"`
Link string `json:"link"`
Image string `json:"image"`
Type string `json:"type"`
Priority string `json:"priority"`
EventType string `json:"event_type"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
Methods map[string]string `json:"methods"`
Metadata map[string]any `json:"metadata"`
Status string `json:"status"`
ScheduledAt int64 `json:"scheduled_at"`
IsScheduled bool `json:"is_scheduled"`
Seen bool `json:"seen"`
SeenAt int64 `json:"seen_at"`
}
// NotificationListResponse represents the response from getting notifications list
type NotificationListResponse struct {
Data []NotificationItem `json:"data"`
Pagination PaginationInfo `json:"pagination"`
}
// PaginationInfo represents pagination information in responses
type PaginationInfo struct {
Total int `json:"total"`
Count int `json:"count"`
PerPage int `json:"per_page"`
CurrentPage int `json:"current_page"`
TotalPages int `json:"total_pages"`
}
// GetNotificationsRequest represents the request parameters for getting notifications
type GetNotificationsRequest struct {
Status string `json:"status,omitempty" valid:"optional"`
Method string `json:"method,omitempty" valid:"optional"`
EventType string `json:"event_type,omitempty" valid:"optional"`
Type string `json:"type,omitempty" valid:"optional"`
UserID string `json:"user_id,omitempty" valid:"optional"`
Seen *bool `json:"seen,omitempty" valid:"optional"`
Priority string `json:"priority,omitempty" valid:"optional"`
Page int `json:"page,omitempty" valid:"optional"`
PerPage int `json:"per_page,omitempty" valid:"optional"`
}
// MarkSeenRequest represents the request for marking a notification as seen
type MarkSeenRequest struct {
NotificationID string `json:"notification_id" valid:"required"`
}
// MarkSeenResponse represents the response from marking a notification as seen
type MarkSeenResponse struct {
Status string `json:"status"`
}