package usecase import ( "fmt" "gateway/internal/model/notification" notifconfig "gateway/internal/model/notification/config" domrepo "gateway/internal/model/notification/domain/repository" domusecase "gateway/internal/model/notification/domain/usecase" "gateway/internal/model/notification/repository" "gateway/internal/model/notification/template" ) // Module bundles notification use cases and background workers. type Module struct { Notifier domusecase.NotifierUseCase Admin domusecase.AdminNotifierUseCase RetryWorker *RetryWorker } func retryQueueKey(cfg notifconfig.Config) string { if cfg.Async.QueueRedisKey != "" { return cfg.Async.QueueRedisKey } return notification.GetRetryZSetRedisKey() } // NewModuleFromParam wires notification repository, notifier, and optional retry worker. func NewModuleFromParam(param FactoryParam) (*Module, error) { if param.MongoConf == nil || param.MongoConf.Host == "" { return nil, fmt.Errorf("notification: mongo config is required") } repo := repository.NewNotificationRepository(repository.NotificationRepositoryParam{ Conf: param.MongoConf, }) dlqRepo := repository.NewNotificationDLQRepository(repository.NotificationDLQRepositoryParam{ Conf: param.MongoConf, }) var idem = repository.NewMemoryIdempotencyCache() var quota = repository.NewMemoryQuotaCounter() var queue domrepo.RetryQueue if param.Redis != nil { idem = repository.NewRedisIdempotencyCache(param.Redis) quota = repository.NewRedisQuotaCounter(param.Redis) queue = repository.NewRedisRetryQueue(param.Redis, retryQueueKey(param.Config)) } emailChain, err := buildEmailChain(param.Config) if err != nil { return nil, err } smsChain, err := buildSMSChain(param.Config) if err != nil { return nil, err } renderer := template.NewRenderer( template.DefaultRegistry(), fallbackLocales(param.Config.DefaultLocale)..., ) notifier := MustNotifierUseCase(NotifierUseCaseParam{ Repo: repo, Idempotency: idem, Quota: quota, RetryQueue: queue, Renderer: renderer, Email: emailChain, SMS: smsChain, Config: param.Config, }) mod := &Module{ Notifier: notifier, Admin: NewAdminNotifierUseCase(AdminNotifierUseCaseParam{ Repo: repo, DLQ: dlqRepo, Queue: queue, }), } if queue != nil { mod.RetryWorker = NewRetryWorker(RetryWorkerParam{ Repo: repo, DLQ: dlqRepo, Queue: queue, Renderer: renderer, Email: emailChain, SMS: smsChain, Config: param.Config, }) } return mod, nil }