package config import ( "context" "fmt" "time" "github.com/go-playground/validator/v10" "github.com/sethvargo/go-envconfig" ) // Config объединяет все необходимые секции конфигурации для вашего проекта. type Config struct { Server ServerConfig `env:",prefix=SERVER_"` DB DBConfig `env:",prefix=DATABASE_"` LLM LLMConfig `env:",prefix=LLM_"` Kafka KafkaConfig `env:",prefix=KAFKA_"` OTEL OTelConfig `env:",prefix=OTEL_"` Telegram TelegramConfig `env:",prefix=TELEGRAM_"` } // ServerConfig содержит параметры HTTP-сервера. type ServerConfig struct { AppName string `env:"APP_NAME,default=ProductAssistant" validate:"required"` Port string `env:"PORT,default=8080" validate:"required"` Secret string `env:"SECRET,default=secret" validate:"required"` } type DBConfig struct { Hostname string `env:"HOSTNAME, default=localhost"` Port int `env:"PORT, default=5435"` User string `env:"USER, default=postgres"` Password string `env:"PASSWORD, default=secret"` Dbname string `env:"DBNAME, default=products_db"` } func (c *DBConfig) ConnectionString() string { return fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=disable", c.Hostname, c.User, c.Password, c.Dbname, c.Port) } // LLMConfig содержит настройки для работы с LLM (модель, API-ключ, endpoint). type LLMConfig struct { Embedder string `env:"EMBEDDER,default=bge-m3" validate:"required"` ModelName string `env:"MODEL_NAME,default=mistral-large-latest" validate:"required"` APIKey string `env:"API_KEY,default=ZdDk5S3QxaEytpf9DWXM2nEb6GVHuF9y" validate:"required"` Endpoint string `env:"ENDPOINT, default=http://localhost:11434" validate:"required,url"` } // KafkaConfig содержит общие настройки для Kafka. type KafkaConfig struct { BootstrapServers []string `env:"BOOTSTRAP_SERVERS, default=localhost:9092" validate:"required,dive,hostname_port"` SSLCertPath string `env:"SSL_CERT_PATH"` SSLKeyPath string `env:"SSL_KEY_PATH"` SSLCaCert string `env:"SSL_CA_CERT"` VerifyCert bool `env:"VERIFY_CERT,default=false"` Producer ProducerConfig `env:",prefix=PRODUCER_"` Consumer ConsumerConfig `env:",prefix=CONSUMER_"` } // ProducerConfig содержит настройки для продюсера Kafka. type ProducerConfig struct { Topic string `env:"TOPIC, default=price_changes" validate:"required"` Async bool `env:"ASYNC, default=false"` AllowAutoTopicCreation bool `env:"ALLOW_AUTO_TOPIC_CREATION, default=true"` } // ConsumerConfig содержит настройки для консьюмера Kafka. type ConsumerConfig struct { Topic string `env:"TOPIC, default=price_changes" validate:"required"` GroupID string `env:"GROUP_ID, default=notifications_group" validate:"required"` } // OTelConfig содержит настройки для OpenTelemetry. type OTelConfig struct { OTLP OTLPConfig `env:",prefix=OTLP_"` } // OTLPConfig задаёт параметры приёма трейсов. type OTLPConfig struct { Insecure bool `env:"INSECURE,default=true"` Endpoint string `env:"ENDPOINT,default=localhost:4317" validate:"required,url"` Timeout time.Duration `env:"TIMEOUT,default=10s"` HTTP bool `env:"HTTP,default=false"` Retry RetryConfig `env:",prefix=RETRY_"` } // RetryConfig содержит настройки повторных попыток для OTLP. type RetryConfig struct { Enabled bool `env:"ENABLED,default=true"` InitialInterval time.Duration `env:"INITIAL_INTERVAL,default=5s"` MaxInterval time.Duration `env:"MAX_INTERVAL,default=30s"` MaxElapsedTime time.Duration `env:"MAX_ELAPSED_TIME,default=1m"` } type TelegramConfig struct { BotToken string `env:"BOT_TOKEN,default=7665408380:AAFKbUgbdQb3iX6X-29H3spv4KGG1FXs_IM" validate:"required"` JWTSecret string `env:"JWT_SECRET,default=secret" validate:"required"` } // NewConfig загружает конфигурацию из переменных окружения и проводит валидацию. func NewConfig(ctx context.Context) (*Config, error) { var cfg Config if err := envconfig.Process(ctx, &cfg); err != nil { return nil, fmt.Errorf("failed to process env config: %w", err) } if err := cfg.Validate(); err != nil { return nil, fmt.Errorf("config validation error: %w", err) } return &cfg, nil } // Validate проверяет корректность настроек с использованием пакета validator. func (c *Config) Validate() error { validate := validator.New() return validate.Struct(c) }