package config import ( "fmt" "os" "github.com/joho/godotenv" ) // Config holds all configuration for the AI Compliance SDK type Config struct { // Server Port string Environment string // Database DatabaseURL string // JWT JWTSecret string // CORS AllowedOrigins []string // Rate Limiting RateLimitRequests int RateLimitWindow int // in seconds // LLM Providers LLMProvider string // 'ollama', 'anthropic', 'openai' LLMFallbackProvider string // Fallback provider if primary fails // Ollama Configuration OllamaURL string OllamaDefaultModel string // Anthropic Configuration AnthropicAPIKey string AnthropicDefaultModel string // OpenAI Configuration (optional) OpenAIAPIKey string OpenAIDefaultModel string // PII Detection PIIRedactionEnabled bool PIIRedactionLevel string // 'strict', 'moderate', 'minimal' // Audit AuditRetentionDays int AuditExportEnabled bool // Valkey/Redis for Caching ValkeyURL string ValkeyEnabled bool // Consent Service Integration ConsentServiceURL string // Frontend URLs AdminFrontendURL string // TTS Service TTSServiceURL string } // Load loads configuration from environment variables func Load() (*Config, error) { // Load .env file if exists (for development) _ = godotenv.Load() cfg := &Config{ Port: getEnv("PORT", "8090"), Environment: getEnv("ENVIRONMENT", "development"), DatabaseURL: getEnv("DATABASE_URL", ""), JWTSecret: getEnv("JWT_SECRET", ""), RateLimitRequests: getEnvInt("RATE_LIMIT_REQUESTS", 100), RateLimitWindow: getEnvInt("RATE_LIMIT_WINDOW", 60), // LLM Configuration LLMProvider: getEnv("LLM_PROVIDER", "ollama"), LLMFallbackProvider: getEnv("LLM_FALLBACK_PROVIDER", "anthropic"), // Ollama OllamaURL: getEnv("OLLAMA_URL", "http://localhost:11434"), OllamaDefaultModel: getEnv("OLLAMA_DEFAULT_MODEL", "qwen2.5:7b"), // Anthropic AnthropicAPIKey: getEnv("ANTHROPIC_API_KEY", ""), AnthropicDefaultModel: getEnv("ANTHROPIC_DEFAULT_MODEL", "claude-3-sonnet-20240229"), // OpenAI OpenAIAPIKey: getEnv("OPENAI_API_KEY", ""), OpenAIDefaultModel: getEnv("OPENAI_DEFAULT_MODEL", "gpt-4-turbo-preview"), // PII PIIRedactionEnabled: getEnvBool("PII_REDACTION_ENABLED", true), PIIRedactionLevel: getEnv("PII_REDACTION_LEVEL", "strict"), // Audit AuditRetentionDays: getEnvInt("AUDIT_RETENTION_DAYS", 365), AuditExportEnabled: getEnvBool("AUDIT_EXPORT_ENABLED", true), // Valkey ValkeyURL: getEnv("VALKEY_URL", "redis://localhost:6379"), ValkeyEnabled: getEnvBool("VALKEY_ENABLED", true), // Integration ConsentServiceURL: getEnv("CONSENT_SERVICE_URL", "http://localhost:8081"), AdminFrontendURL: getEnv("ADMIN_FRONTEND_URL", "http://localhost:3002"), TTSServiceURL: getEnv("TTS_SERVICE_URL", "http://compliance-tts-service:8095"), } // Parse allowed origins originsStr := getEnv("ALLOWED_ORIGINS", "http://localhost:3000,http://localhost:3002,http://localhost:8000") cfg.AllowedOrigins = parseCommaSeparated(originsStr) // Validate required fields if cfg.DatabaseURL == "" { return nil, fmt.Errorf("DATABASE_URL is required") } if cfg.JWTSecret == "" { return nil, fmt.Errorf("JWT_SECRET is required") } return cfg, nil } func getEnv(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue } func getEnvInt(key string, defaultValue int) int { if value := os.Getenv(key); value != "" { var result int fmt.Sscanf(value, "%d", &result) return result } return defaultValue } func getEnvBool(key string, defaultValue bool) bool { if value := os.Getenv(key); value != "" { return value == "true" || value == "1" || value == "yes" } return defaultValue } func parseCommaSeparated(s string) []string { if s == "" { return []string{} } var result []string start := 0 for i := 0; i <= len(s); i++ { if i == len(s) || s[i] == ',' { item := s[start:i] // Trim whitespace for len(item) > 0 && item[0] == ' ' { item = item[1:] } for len(item) > 0 && item[len(item)-1] == ' ' { item = item[:len(item)-1] } if item != "" { result = append(result, item) } start = i + 1 } } return result } // IsDevelopment returns true if running in development mode func (c *Config) IsDevelopment() bool { return c.Environment == "development" } // IsProduction returns true if running in production mode func (c *Config) IsProduction() bool { return c.Environment == "production" }