diff --git a/internal/notification/entity.go b/internal/notification/entity.go index 95292b8..7782444 100644 --- a/internal/notification/entity.go +++ b/internal/notification/entity.go @@ -28,8 +28,26 @@ const ( DeliveryChannelInApp DeliveryChannel = "in_app" ) -// EventTypeInApp identifies notifications stored for the in-app notification center. -const EventTypeInApp = "in_app" +// Persisted event types for stored notifications (admin list / notification center). +const ( + EventTypeInApp = "in_app" + EventTypeEmail = "email" + EventTypePush = "push" +) + +// persistedEventType maps a delivery channel to the event_type stored in MongoDB. +func persistedEventType(channel DeliveryChannel) (string, bool) { + switch channel { + case DeliveryChannelEmail: + return EventTypeEmail, true + case DeliveryChannelPush: + return EventTypePush, true + case DeliveryChannelInApp: + return EventTypeInApp, true + default: + return "", false + } +} // DeliveryStatus represents the delivery status of notification type NotificationStatus string diff --git a/internal/notification/service.go b/internal/notification/service.go index e14e072..f2f1fd8 100644 --- a/internal/notification/service.go +++ b/internal/notification/service.go @@ -99,13 +99,27 @@ func (s *notificationService) Send(ctx context.Context, req *NotificationRequest } func (s *notificationService) sendToRecipient(ctx context.Context, recipient notificationRecipient, req *NotificationRequest, link, image string) { - if err := s.persistNotification(ctx, recipient, req, link, image); err != nil { + // Always persist an in-app record so every send appears in the notification center. + if err := s.persistNotification(ctx, recipient, req, link, image, DeliveryChannelInApp); err != nil { s.logger.Error("Failed to persist in-app notification", map[string]interface{}{ "error": err.Error(), "user_id": recipient.UserID, }) } + for _, channel := range req.Channels { + if channel == DeliveryChannelInApp { + continue + } + if err := s.persistNotification(ctx, recipient, req, link, image, channel); err != nil { + s.logger.Error("Failed to persist notification", map[string]interface{}{ + "error": err.Error(), + "user_id": recipient.UserID, + "channel": channel, + }) + } + } + metadata := map[string]any{ "tender": strings.TrimSpace(req.Tender), } @@ -149,15 +163,26 @@ func (s *notificationService) sendToRecipient(ctx context.Context, recipient not } } -func (s *notificationService) persistNotification(ctx context.Context, recipient notificationRecipient, req *NotificationRequest, link, image string) error { - methods := map[string]string{ - "in_app": "true", +func (s *notificationService) persistNotification(ctx context.Context, recipient notificationRecipient, req *NotificationRequest, link, image string, channel DeliveryChannel) error { + eventType, ok := persistedEventType(channel) + if !ok { + return nil } - if slices.Contains(req.Channels, DeliveryChannelEmail) && recipient.Email != "" { + + methods := map[string]string{} + switch channel { + case DeliveryChannelEmail: + if recipient.Email == "" { + return nil + } methods["email"] = recipient.Email - } - if slices.Contains(req.Channels, DeliveryChannelPush) && len(recipient.DeviceTokens) > 0 { + case DeliveryChannelPush: + if len(recipient.DeviceTokens) == 0 { + return nil + } methods["push"] = recipient.DeviceTokens[0] + case DeliveryChannelInApp: + methods["in_app"] = "true" } status := string(DeliveryStatusSent) @@ -173,7 +198,7 @@ func (s *notificationService) persistNotification(ctx context.Context, recipient Image: image, Priority: string(req.Priority), Type: string(req.Type), - EventType: EventTypeInApp, + EventType: eventType, Status: status, Methods: methods, Metadata: map[string]any{