-
Шаронов Егор Алексеевич authored
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"`
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
}
// 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)
}