package config import ( "errors" "os" ) // Config holds runtime configuration for the alert-bridge process. type Config struct { HTTPPort string // HTTP_PORT, default "8080" APIKey string // API_KEY — required bearer token callers must present in Authorization: Bearer DiscordWebhookURL string // DISCORD_WEBHOOK_URL — required, the target channel's Discord Incoming Webhook URL MentionUserID string // MENTION_USER_ID — optional Discord user ID; when set, level=error alerts mention this user OTELEndpoint string LogLevel string LogFormat string } // Load reads alert-bridge configuration from environment variables. func Load() (*Config, error) { apiKey := os.Getenv("API_KEY") if apiKey == "" { return nil, errors.New("API_KEY is required but not set") } webhookURL := os.Getenv("DISCORD_WEBHOOK_URL") if webhookURL == "" { return nil, errors.New("DISCORD_WEBHOOK_URL is required but not set") } return &Config{ HTTPPort: getenvDefault("HTTP_PORT", "8080"), APIKey: apiKey, DiscordWebhookURL: webhookURL, MentionUserID: os.Getenv("MENTION_USER_ID"), OTELEndpoint: os.Getenv("OTEL_ENDPOINT"), LogLevel: getenvDefault("LOG_LEVEL", "info"), LogFormat: getenvDefault("LOG_FORMAT", "json"), }, nil } // getenvDefault keeps config loading concise for optional variables with defaults. func getenvDefault(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback }