template-monorepo/internal/model/notification/usecase/module.go

96 lines
2.5 KiB
Go

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, param.Redis)
if err != nil {
return nil, err
}
smsChain, err := buildSMSChain(param.Config, param.Redis)
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
}