9037cb5917
- Updated the notification handling logic to utilize a new SDK for sending notifications, improving the flexibility and scalability of the notification system. - Introduced new methods in the notification service for sending notifications to users and customers based on various target audience types, enhancing the notification delivery capabilities. - Added a new endpoint to assign companies to a customer, improving customer management functionalities. - Refactored the customer entity and forms to replace 'CompanyIDs' with 'Companies', ensuring consistency across the data model. - Enhanced API documentation with Swagger comments for the new endpoint and updated notification structures, ensuring clarity for API consumers.
119 lines
3.8 KiB
Go
119 lines
3.8 KiB
Go
package notification
|
|
|
|
import (
|
|
"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,omitempty" valid:"optional"`
|
|
Title string `json:"title" valid:"required"`
|
|
Message string `json:"message" valid:"required,length(1|1000)"`
|
|
Type string `json:"type" valid:"required,in(info|warning|alert|reject)"`
|
|
EventType EventType `json:"event_type" valid:"required,in(EMAIL|SMS|PUSH|OTP)"`
|
|
Priority string `json:"priority" valid:"required,in(low|medium|important)"`
|
|
ScheduledAt int64 `json:"scheduled_at"`
|
|
Metadata map[string]any `json:"metadata,omitempty" valid:"optional"`
|
|
Methods NotificationMethods `json:"methods" valid:"required"`
|
|
}
|
|
|
|
// NotificationResponse represents the successful response from notification service
|
|
type NotificationResponse struct {
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
// 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
|
|
}
|