package config import ( "os" "strconv" ) // Config holds all runtime configuration loaded from environment variables. type Config struct { Port string OpenAIBackend string OpenAIApiKey string PostgresDSN string DBPath string // SQLite database file path (when DB_MODE=sqlite) DBMode string // "sqlite" or "pgs" — selects database driver LogLevel string // "debug", "info", or "warn" — console log verbosity RequestTimeoutSeconds int OpenAIModel string // default model when client omits it } // Load reads environment variables and returns a populated Config. // All values MUST come from env — no hardcoded IPs or ports. func Load() *Config { timeoutSec := 30 if v := os.Getenv("REQUEST_TIMEOUT_SECONDS"); v != "" { if parsed, err := strconv.Atoi(v); err == nil { timeoutSec = parsed } } dbMode := os.Getenv("DB_MODE") dbPath := os.Getenv("DB_PATH") logLevel := os.Getenv("LOG_LEVEL") // Support both POSTGRES_DSN and DATABASE_DSN env keys postgresDSN := os.Getenv("POSTGRES_DSN") if postgresDSN == "" { postgresDSN = os.Getenv("DATABASE_DSN") } port := os.Getenv("PORT") if port == "" { port = "8000" } openAIBackend := os.Getenv("OPENAI_BACKEND") if openAIBackend == "" { openAIBackend = "https://api.deepseek.com" } openAIApiKey := os.Getenv("OPENAI_KEY") openAIModel := os.Getenv("OPENAI_MODEL") return &Config{ Port: port, OpenAIBackend: openAIBackend, OpenAIApiKey: openAIApiKey, PostgresDSN: postgresDSN, DBPath: dbPath, DBMode: dbMode, LogLevel: logLevel, RequestTimeoutSeconds: timeoutSec, OpenAIModel: openAIModel, } }