package workflows import ( "context" "fmt" "log/slog" "go.temporal.io/sdk/client" ) // ClientConfig holds configuration for the Temporal client. type ClientConfig struct { HostPort string Namespace string Logger *slog.Logger OAuthTokenProvider *OAuthTokenProviderConfig } // DefaultClientConfig returns a ClientConfig with sensible defaults. func DefaultClientConfig() ClientConfig { return ClientConfig{ HostPort: "localhost:7233", Namespace: "default", } } // NewClient creates a new Temporal client. func NewClient(ctx context.Context, cfg ClientConfig) (client.Client, error) { if cfg.HostPort == "" { cfg.HostPort = "localhost:7233" } if cfg.Namespace == "" { cfg.Namespace = "default" } opts := client.Options{ HostPort: cfg.HostPort, Namespace: cfg.Namespace, } if cfg.OAuthTokenProvider != nil { headersProvider, err := NewOAuthTokenProvider(*cfg.OAuthTokenProvider) if err != nil { return nil, fmt.Errorf("failed to configure Temporal auth: %w", err) } opts.HeadersProvider = headersProvider } if cfg.Logger != nil { opts.Logger = newSlogAdapter(cfg.Logger) } c, err := client.Dial(opts) if err != nil { return nil, fmt.Errorf("failed to create Temporal client: %w", err) } if cfg.Logger != nil { cfg.Logger.Info("connected to Temporal server", slog.String("host", cfg.HostPort), slog.String("namespace", cfg.Namespace)) } return c, nil } // slogAdapter adapts slog.Logger to Temporal's log.Logger interface. type slogAdapter struct { logger *slog.Logger } func newSlogAdapter(logger *slog.Logger) *slogAdapter { return &slogAdapter{logger: logger} } func (s *slogAdapter) Debug(msg string, keyvals ...interface{}) { s.logger.Debug(msg, keyvals...) } func (s *slogAdapter) Info(msg string, keyvals ...interface{}) { s.logger.Info(msg, keyvals...) } func (s *slogAdapter) Warn(msg string, keyvals ...interface{}) { s.logger.Warn(msg, keyvals...) } func (s *slogAdapter) Error(msg string, keyvals ...interface{}) { s.logger.Error(msg, keyvals...) }