package config import ( "errors" "os" "strings" ) type Config struct { Environment string Port string APIURL string FrontendURL string DatabaseURL string DatabaseDirectURL string NeonAuthURL string JobRunnerKey string EmailFrom string SMSFrom string StripeSecretKey string StripeWebhookKey string StripePriceIDs map[string]string } func Load() (Config, error) { cfg := Config{ Environment: valueOrDefault("BOOKRA_APP_ENV", "development"), Port: valueOrDefault("BOOKRA_API_PORT", "8080"), APIURL: valueOrDefault("BOOKRA_API_URL", "http://localhost:8080"), FrontendURL: valueOrDefault("BOOKRA_FRONTEND_URL", "http://localhost:3000"), DatabaseURL: strings.TrimSpace(os.Getenv("BOOKRA_DATABASE_URL")), DatabaseDirectURL: strings.TrimSpace(os.Getenv("BOOKRA_DATABASE_DIRECT_URL")), NeonAuthURL: strings.TrimSpace(os.Getenv("BOOKRA_NEON_AUTH_URL")), JobRunnerKey: strings.TrimSpace(os.Getenv("BOOKRA_JOB_RUNNER_KEY")), EmailFrom: valueOrDefault("BOOKRA_EMAIL_FROM", "noreply@bookra.dev"), SMSFrom: valueOrDefault("BOOKRA_SMS_FROM", "Bookra"), StripeSecretKey: strings.TrimSpace(os.Getenv("BOOKRA_STRIPE_SECRET_KEY")), StripeWebhookKey: strings.TrimSpace(os.Getenv("BOOKRA_STRIPE_WEBHOOK_SECRET")), StripePriceIDs: map[string]string{ "starter": strings.TrimSpace(os.Getenv("BOOKRA_STRIPE_STARTER_PRICE_ID")), "growth": strings.TrimSpace(os.Getenv("BOOKRA_STRIPE_GROWTH_PRICE_ID")), "multi-location": strings.TrimSpace(os.Getenv("BOOKRA_STRIPE_MULTI_LOCATION_PRICE_ID")), }, } if cfg.FrontendURL == "" { return Config{}, errors.New("BOOKRA_FRONTEND_URL is required") } return cfg, nil } func valueOrDefault(key string, fallback string) string { if value := strings.TrimSpace(os.Getenv(key)); value != "" { return value } return fallback }