package config import ( "context" "fmt" "os" "strconv" ) type Config struct { ServerPort string BaseURL string JWTSecret string UploadPath string DatabaseHost string DatabasePort string DatabaseUser string DatabasePassword string DatabaseName string TestMode bool RateLimitEnabled bool RequestsPerMinute int } func LoadConfig() *Config { port := getEnv("SERVER_PORT", "8765") return &Config{ ServerPort: port, BaseURL: getEnv("BASE_URL", "http://localhost:"+port), DatabaseHost: getEnv("DATABASE_HOST", "localhost"), DatabasePort: getEnv("DATABASE_PORT", "5432"), DatabaseUser: getEnv("DATABASE_USER", "postgres"), DatabasePassword: getEnv("DATABASE_PASSWORD", "password"), DatabaseName: getEnv("DATABASE_NAME", "bookhoard"), JWTSecret: getEnv("JWT_SECRET", "your-secret-key"), UploadPath: getEnv("UPLOAD_PATH", "./uploads"), TestMode: getEnvBool("TEST_MODE", false), RateLimitEnabled: getEnvBool("RATE_LIMIT_ENABLED", true), RequestsPerMinute: getEnvInt("REQUESTS_PER_MINUTE", 10), } } func (c *Config) DatabaseURL() string { return fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable", c.DatabaseUser, c.DatabasePassword, c.DatabaseHost, c.DatabasePort, c.DatabaseName) } // GetBaseURL returns the base URL from system configuration database with fallback to config/env var func GetBaseURL(ctx context.Context, db interface{}) string { // Try to get from database first type SystemConfigQuerier interface { GetSystemConfig(ctx context.Context, key string) (SystemConfigRow, error) } if querier, ok := db.(SystemConfigQuerier); ok { config, err := querier.GetSystemConfig(ctx, "base_url") if err == nil && config.Value != "" { return config.Value } } // Fallback: return empty string - caller should use their own fallback return "" } // SystemConfigRow represents a system configuration row type SystemConfigRow struct { Key string Value string } func getEnv(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue } func getEnvBool(key string, defaultValue bool) bool { if value := os.Getenv(key); value != "" { boolVal, err := strconv.ParseBool(value) if err == nil { return boolVal } } return defaultValue } func getEnvInt(key string, defaultValue int) int { if value := os.Getenv(key); value != "" { intVal, err := strconv.Atoi(value) if err == nil { return intVal } } return defaultValue }