package config import ( "os" "strconv" "time" "gopkg.in/yaml.v3" ) type Config struct { Server ServerConfig `yaml:"server"` Database DatabaseConfig `yaml:"database"` Redis RedisConfig `yaml:"redis"` JWT JWTConfig `yaml:"jwt"` CORS CORSConfig `yaml:"cors"` Logging LoggingConfig `yaml:"logging"` Email EmailConfig `yaml:"email"` Frontend FrontendConfig `yaml:"frontend"` } type ServerConfig struct { Host string `yaml:"host"` Port int `yaml:"port"` Mode string `yaml:"mode"` ReadTimeout int `yaml:"read_timeout"` WriteTimeout int `yaml:"write_timeout"` IdleTimeout int `yaml:"idle_timeout"` } func (s *ServerConfig) Address() string { return s.Host + ":" + strconv.Itoa(s.Port) } func (s *ServerConfig) ReadTimeoutDuration() time.Duration { return time.Duration(s.ReadTimeout) * time.Second } func (s *ServerConfig) WriteTimeoutDuration() time.Duration { return time.Duration(s.WriteTimeout) * time.Second } func (s *ServerConfig) IdleTimeoutDuration() time.Duration { return time.Duration(s.IdleTimeout) * time.Second } type DatabaseConfig struct { Host string `yaml:"host"` Port int `yaml:"port"` User string `yaml:"user"` Password string `yaml:"password"` Name string `yaml:"name"` SSLMode string `yaml:"ssl_mode"` MaxOpenConns int `yaml:"max_open_conns"` MaxIdleConns int `yaml:"max_idle_conns"` ConnMaxLifetime int `yaml:"conn_max_lifetime"` } func (d *DatabaseConfig) DSN() string { return "host=" + d.Host + " port=" + strconv.Itoa(d.Port) + " user=" + d.User + " password=" + d.Password + " dbname=" + d.Name + " sslmode=" + d.SSLMode } type RedisConfig struct { Host string `yaml:"host"` Port int `yaml:"port"` Password string `yaml:"password"` DB int `yaml:"db"` } func (r *RedisConfig) Address() string { return r.Host + ":" + strconv.Itoa(r.Port) } type JWTConfig struct { Secret string `yaml:"secret"` ExpiresIn int `yaml:"expires_in"` RefreshExpiresIn int `yaml:"refresh_expires_in"` } func (j *JWTConfig) ExpiresInDuration() time.Duration { return time.Duration(j.ExpiresIn) * time.Hour } func (j *JWTConfig) RefreshExpiresInDuration() time.Duration { return time.Duration(j.RefreshExpiresIn) * time.Hour } type CORSConfig struct { AllowedOrigins []string `yaml:"allowed_origins"` AllowedMethods []string `yaml:"allowed_methods"` AllowedHeaders []string `yaml:"allowed_headers"` AllowCredentials bool `yaml:"allow_credentials"` MaxAge int `yaml:"max_age"` } type LoggingConfig struct { Level string `yaml:"level"` Format string `yaml:"format"` Output string `yaml:"output"` } type EmailConfig struct { SMTPHost string `yaml:"smtp_host"` SMTPPort int `yaml:"smtp_port"` Username string `yaml:"username"` Password string `yaml:"password"` FromAddress string `yaml:"from_address"` FromName string `yaml:"from_name"` } type FrontendConfig struct { BuildPath string `yaml:"build_path"` SPAFallback bool `yaml:"spa_fallback"` } var cfg *Config func Load(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { return nil, err } cfg = &Config{} if err := yaml.Unmarshal(data, cfg); err != nil { return nil, err } return cfg, nil } func Get() *Config { return cfg }