// Package notificationpublisher provides the Redis-Streams-backed // notification-intent publisher Runtime Manager uses to emit admin-only // failure notifications. The adapter is a thin shim over // `galaxy/notificationintent.Publisher` that drops the entry id at the // wrapper boundary; rationale lives in // `rtmanager/docs/domain-and-ports.md ยง7`. package notificationpublisher import ( "context" "errors" "fmt" "github.com/redis/go-redis/v9" "galaxy/notificationintent" "galaxy/rtmanager/internal/ports" ) // Config groups the dependencies and stream name required to // construct a Publisher. type Config struct { // Client appends entries to Redis Streams. Must be non-nil. Client *redis.Client // Stream stores the Redis Stream key intents are published to. // When empty, `notificationintent.DefaultIntentsStream` is used. Stream string } // Publisher implements `ports.NotificationIntentPublisher` on top of // the shared `notificationintent.Publisher`. The wrapper is the single // point that drops the entry id returned by the underlying publisher. type Publisher struct { inner *notificationintent.Publisher } // NewPublisher constructs a Publisher from cfg. It wraps the shared // publisher and delegates validation; transport errors and validation // errors propagate verbatim. func NewPublisher(cfg Config) (*Publisher, error) { if cfg.Client == nil { return nil, errors.New("new rtmanager notification publisher: nil redis client") } inner, err := notificationintent.NewPublisher(notificationintent.PublisherConfig{ Client: cfg.Client, Stream: cfg.Stream, }) if err != nil { return nil, fmt.Errorf("new rtmanager notification publisher: %w", err) } return &Publisher{inner: inner}, nil } // Publish forwards intent to the underlying notificationintent // publisher and discards the resulting Redis Stream entry id. A failed // publish surfaces as the underlying error. func (publisher *Publisher) Publish(ctx context.Context, intent notificationintent.Intent) error { if publisher == nil || publisher.inner == nil { return errors.New("publish notification intent: nil publisher") } if _, err := publisher.inner.Publish(ctx, intent); err != nil { return err } return nil } // Compile-time assertion: Publisher implements // ports.NotificationIntentPublisher. var _ ports.NotificationIntentPublisher = (*Publisher)(nil)