package config import ( "fmt" "strings" "github.com/spf13/viper" ) // Config represents the application configuration type Config struct { Server struct { Port int `mapstructure:"port"` ReadTimeoutSeconds int `mapstructure:"read_timeout_seconds"` WriteTimeoutSeconds int `mapstructure:"write_timeout_seconds"` IdleTimeoutSeconds int `mapstructure:"idle_timeout_seconds"` } `mapstructure:"server"` LogLevel string `mapstructure:"log_level"` Google struct { ProjectID string `mapstructure:"project_id"` Location string `mapstructure:"location"` Dataset string `mapstructure:"dataset"` DicomStore string `mapstructure:"dicom_store"` CredentialsPath string `mapstructure:"credentials_path"` } `mapstructure:"google"` Auth struct { JWTSecret string `mapstructure:"jwt_secret"` AccessTokenExpiry int `mapstructure:"access_token_expiry"` // in minutes RefreshTokenExpiry int `mapstructure:"refresh_token_expiry"` // in hours EnableDatabaseAuth bool `mapstructure:"enable_database_auth"` } `mapstructure:"auth"` Shortlink struct { BaseURL string `mapstructure:"base_url"` // Base URL for shortlinks (e.g., https://example.com) DefaultExpiryHours int `mapstructure:"default_expiry_hours"` // Default expiry time in hours MaxAttempts int `mapstructure:"max_attempts"` // Maximum failed attempts allowed } `mapstructure:"shortlink"` Database struct { Host string `mapstructure:"host"` Port int `mapstructure:"port"` User string `mapstructure:"user"` Password string `mapstructure:"password"` Name string `mapstructure:"name"` MaxOpenConns int `mapstructure:"max_open_conns"` MaxIdleConns int `mapstructure:"max_idle_conns"` ConnMaxLifetimeMins int `mapstructure:"conn_max_lifetime_mins"` } `mapstructure:"database"` AllowedOrigins []string `mapstructure:"allowed_origins"` } // Load reads configuration from file and environment variables func Load() (*Config, error) { viper.SetConfigName("config") viper.SetConfigType("yaml") viper.AddConfigPath("./config") viper.AddConfigPath(".") viper.AutomaticEnv() viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) if err := viper.ReadInConfig(); err != nil { return nil, fmt.Errorf("failed to read config file: %w", err) } var cfg Config if err := viper.Unmarshal(&cfg); err != nil { return nil, fmt.Errorf("failed to unmarshal config: %w", err) } return &cfg, nil }