package aapitemplate import ( "github.com/tech/sendico/pkg/messaging" notifications "github.com/tech/sendico/pkg/messaging/envelope" model "github.com/tech/sendico/pkg/model/notification" "go.mongodb.org/mongo-driver/v2/bson" ) // NotificationHandler is a function that processes an object of type T and returns an error. type NotificationHandler[T any] func(template T, actorAccountRef bson.ObjectID) error // sinkNotification is the default no-op strategy. func sinkNotification[T any](_ T, _ bson.ObjectID) error { return nil } // NotificationConfig manages notifications for Create, Update, and Delete operations. type NotificationConfig[T any] struct { producer messaging.Producer // The factory now receives a NotificationAction so it knows which event is being processed. factory func(template T, actorAccountRef bson.ObjectID, t model.NotificationAction) notifications.Envelope CreateNotification NotificationHandler[T] UpdateNotification NotificationHandler[T] NeedArchiveNotification bool ArchiveNotification NotificationHandler[T] NeedDeleteNotification bool DeleteNotification NotificationHandler[T] } // NewNotificationConfig creates a new NotificationConfig with default (no-op) strategies. func NewNotificationConfig[T any](producer messaging.Producer) *NotificationConfig[T] { return &NotificationConfig[T]{ producer: producer, factory: nil, // no factory by default CreateNotification: sinkNotification[T], UpdateNotification: sinkNotification[T], ArchiveNotification: sinkNotification[T], NeedArchiveNotification: false, DeleteNotification: sinkNotification[T], NeedDeleteNotification: false, } } // WithNotifications sets the notification factory and switches all endpoints to the sending strategy. func (nc *NotificationConfig[T]) WithNotifications(factory func(template T, actorAccountRef bson.ObjectID, typ model.NotificationAction) notifications.Envelope) *NotificationConfig[T] { nc.factory = factory // Build sending functions for each notification type. nc.CreateNotification = func(template T, actorAccountRef bson.ObjectID) error { return nc.producer.SendMessage(factory(template, actorAccountRef, model.NACreated)) } nc.UpdateNotification = func(template T, actorAccountRef bson.ObjectID) error { return nc.producer.SendMessage(factory(template, actorAccountRef, model.NAUpdated)) } nc.ArchiveNotification = func(template T, actorAccountRef bson.ObjectID) error { return nc.producer.SendMessage(factory(template, actorAccountRef, model.NAArchived)) } nc.NeedArchiveNotification = true nc.DeleteNotification = func(template T, actorAccountRef bson.ObjectID) error { return nc.producer.SendMessage(factory(template, actorAccountRef, model.NADeleted)) } nc.NeedDeleteNotification = true return nc } // WithNoCreateNotification disables the create notification. func (nc *NotificationConfig[T]) WithNoCreateNotification() *NotificationConfig[T] { nc.CreateNotification = sinkNotification[T] return nc } // WithNoUpdateNotification disables the update notification. func (nc *NotificationConfig[T]) WithNoUpdateNotification() *NotificationConfig[T] { nc.UpdateNotification = sinkNotification[T] return nc } func (nc *NotificationConfig[T]) WithNoArchiveNotification() *NotificationConfig[T] { nc.ArchiveNotification = sinkNotification[T] return nc } // WithNoDeleteNotification disables the delete notification. func (nc *NotificationConfig[T]) WithNoDeleteNotification() *NotificationConfig[T] { nc.DeleteNotification = sinkNotification[T] nc.NeedDeleteNotification = false return nc }