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 { EventType EventType `json:"event_type" valid:"required,in(EMAIL|SMS|PUSH|OTP)"` Message string `json:"message" valid:"required,length(1|1000)"` Methods NotificationMethods `json:"methods" valid:"required"` UserID string `json:"user_id,omitempty" valid:"optional"` } // 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"} } } 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 "" } }