Files
skybridge/user/internal/config/config.go
2025-08-31 22:35:23 -04:00

167 lines
3.8 KiB
Go

package config
import (
"fmt"
"os"
"strconv"
"strings"
"time"
"github.com/joho/godotenv"
)
// ConfigProvider defines the interface for configuration operations
type ConfigProvider interface {
GetString(key string) string
GetInt(key string) int
GetBool(key string) bool
GetDuration(key string) time.Duration
IsSet(key string) bool
Validate() error
GetDatabaseDSN() string
GetDatabaseDSNForLogging() string
GetServerAddress() string
IsProduction() bool
}
// Config implements the ConfigProvider interface
type Config struct {
defaults map[string]string
}
// NewConfig creates a new configuration instance
func NewConfig() ConfigProvider {
// Load .env file if it exists
_ = godotenv.Load()
return &Config{
defaults: map[string]string{
"SERVER_HOST": "0.0.0.0",
"SERVER_PORT": "8090",
"SERVER_READ_TIMEOUT": "30s",
"SERVER_WRITE_TIMEOUT": "30s",
"SERVER_IDLE_TIMEOUT": "60s",
"DB_HOST": "localhost",
"DB_PORT": "5432",
"DB_NAME": "users",
"DB_USER": "postgres",
"DB_PASSWORD": "postgres",
"DB_SSLMODE": "disable",
"DB_MAX_OPEN_CONNS": "25",
"DB_MAX_IDLE_CONNS": "5",
"DB_CONN_MAX_LIFETIME": "5m",
"APP_ENV": "development",
"APP_VERSION": "1.0.0",
"LOG_LEVEL": "debug",
"RATE_LIMIT_ENABLED": "true",
"RATE_LIMIT_RPS": "100",
"RATE_LIMIT_BURST": "200",
"AUTH_PROVIDER": "header",
"AUTH_HEADER_USER_EMAIL": "X-User-Email",
},
}
}
func (c *Config) GetString(key string) string {
if value := os.Getenv(key); value != "" {
return value
}
return c.defaults[key]
}
func (c *Config) GetInt(key string) int {
value := c.GetString(key)
if value == "" {
return 0
}
intVal, err := strconv.Atoi(value)
if err != nil {
return 0
}
return intVal
}
func (c *Config) GetBool(key string) bool {
value := strings.ToLower(c.GetString(key))
return value == "true" || value == "1"
}
func (c *Config) GetDuration(key string) time.Duration {
value := c.GetString(key)
if value == "" {
return 0
}
duration, err := time.ParseDuration(value)
if err != nil {
return 0
}
return duration
}
func (c *Config) IsSet(key string) bool {
return os.Getenv(key) != "" || c.defaults[key] != ""
}
func (c *Config) Validate() error {
required := []string{
"SERVER_HOST",
"SERVER_PORT",
"DB_HOST",
"DB_PORT",
"DB_NAME",
"DB_USER",
"DB_PASSWORD",
}
var missing []string
for _, key := range required {
if c.GetString(key) == "" {
missing = append(missing, key)
}
}
if len(missing) > 0 {
return fmt.Errorf("missing required configuration keys: %s", strings.Join(missing, ", "))
}
return nil
}
func (c *Config) GetDatabaseDSN() string {
host := c.GetString("DB_HOST")
port := c.GetString("DB_PORT")
user := c.GetString("DB_USER")
password := c.GetString("DB_PASSWORD")
dbname := c.GetString("DB_NAME")
sslmode := c.GetString("DB_SSLMODE")
// Debug logging to see what values we're getting
// fmt.Printf("DEBUG DSN VALUES: host=%s port=%s user=%s password=%s dbname=%s sslmode=%s\n",
// host, port, user, password, dbname, sslmode)
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
host, port, user, password, dbname, sslmode)
return dsn
}
func (c *Config) GetDatabaseDSNForLogging() string {
return fmt.Sprintf("host=%s port=%s user=%s dbname=%s sslmode=%s",
c.GetString("DB_HOST"),
c.GetString("DB_PORT"),
c.GetString("DB_USER"),
c.GetString("DB_NAME"),
c.GetString("DB_SSLMODE"),
)
}
func (c *Config) GetServerAddress() string {
return fmt.Sprintf("%s:%s", c.GetString("SERVER_HOST"), c.GetString("SERVER_PORT"))
}
func (c *Config) IsProduction() bool {
return strings.ToLower(c.GetString("APP_ENV")) == "production"
}