Frontend: - Refatoração completa do [GestaoUsuarioModal](cci:1://file:///c:/Projetos/saveinmed/saveinmed-frontend/src/components/GestaoUsuarioModal.tsx:17:0-711:2) para melhor visibilidade e UX. - Correção de erro (crash) ao carregar endereços vazios. - Nova interface de Configuração de Frete com abas para Entrega e Retirada. - Correção na busca de dados completos da empresa (CEP, etc). - Ajuste na chave de autenticação (`access_token`) no serviço de endereços. Backend: - Correção do erro 500 em [GetShippingSettings](cci:1://file:///c:/Projetos/saveinmed/backend-old/internal/repository/postgres/postgres.go:1398:0-1405:1) (tratamento de `no rows`). - Ajustes nos handlers de endereço para suportar Admin/EntityID corretamente. - Migrações de banco de dados para configurações de envio e coordenadas. - Atualização da documentação Swagger e testes.
119 lines
3.7 KiB
Go
119 lines
3.7 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/joho/godotenv"
|
|
)
|
|
|
|
// Config centralizes runtime configuration loaded from the environment.
|
|
type Config struct {
|
|
AppName string
|
|
Port string
|
|
DatabaseURL string
|
|
MercadoPagoBaseURL string
|
|
MercadoPagoAccessToken string
|
|
MarketplaceCommission float64
|
|
BuyerFeeRate float64 // Fee rate applied to buyer prices (e.g., 0.12 = 12%)
|
|
JWTSecret string
|
|
JWTExpiresIn time.Duration
|
|
PasswordPepper string
|
|
CORSOrigins []string
|
|
BackendHost string
|
|
SwaggerSchemes []string
|
|
AdminName string
|
|
AdminUsername string
|
|
AdminEmail string
|
|
AdminPassword string
|
|
MercadoPagoPublicKey string
|
|
MapboxAccessToken string
|
|
}
|
|
|
|
// Load reads configuration from environment variables and applies sane defaults
|
|
// for local development.
|
|
func Load() (*Config, error) {
|
|
_ = godotenv.Load() // Load from .env if present
|
|
|
|
cfg := Config{
|
|
AppName: getEnv("APP_NAME", "saveinmed-performance-core"),
|
|
Port: getEnv("BACKEND_PORT", "8214"),
|
|
DatabaseURL: getEnv("DATABASE_URL", "postgres://postgres:postgres@localhost:5432/saveinmed?sslmode=disable"),
|
|
MercadoPagoBaseURL: getEnv("MERCADOPAGO_BASE_URL", "https://api.mercadopago.com"),
|
|
MercadoPagoAccessToken: getEnv("MERCADOPAGO_ACCESS_TOKEN", "TEST-00000000-0000-0000-0000-000000000000"), // Default dummy
|
|
MarketplaceCommission: getEnvFloat("MARKETPLACE_COMMISSION", 2.5),
|
|
BuyerFeeRate: getEnvFloat("BUYER_FEE_RATE", 0.12), // 12% invisible fee
|
|
JWTSecret: getEnv("JWT_SECRET", "dev-secret"),
|
|
JWTExpiresIn: getEnvDuration("JWT_EXPIRES_IN", 24*time.Hour),
|
|
PasswordPepper: getEnv("PASSWORD_PEPPER", ""),
|
|
CORSOrigins: getEnvStringSlice("CORS_ORIGINS", []string{"*"}),
|
|
BackendHost: getEnv("BACKEND_HOST", ""),
|
|
SwaggerSchemes: getEnvStringSlice("SWAGGER_SCHEMES", []string{"http"}),
|
|
AdminName: getEnv("ADMIN_NAME", "Administrator"),
|
|
AdminUsername: getEnv("ADMIN_USERNAME", "admin"),
|
|
AdminEmail: getEnv("ADMIN_EMAIL", "admin@saveinmed.com"),
|
|
AdminPassword: getEnv("ADMIN_PASSWORD", "admin123"),
|
|
MercadoPagoPublicKey: getEnv("MERCADOPAGO_PUBLIC_KEY", "TEST-PUBLIC-KEY"),
|
|
MapboxAccessToken: getEnv("MAPBOX_ACCESS_TOKEN", ""),
|
|
}
|
|
|
|
return &cfg, nil
|
|
}
|
|
|
|
// Addr returns the address binding for the HTTP server.
|
|
func (c Config) Addr() string {
|
|
return fmt.Sprintf(":%s", c.Port)
|
|
}
|
|
|
|
func getEnv(key, fallback string) string {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvInt(key string, fallback int) int {
|
|
if value := os.Getenv(key); value != "" {
|
|
if parsed, err := strconv.Atoi(value); err == nil {
|
|
return parsed
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvDuration(key string, fallback time.Duration) time.Duration {
|
|
if value := os.Getenv(key); value != "" {
|
|
if parsed, err := time.ParseDuration(value); err == nil {
|
|
return parsed
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvFloat(key string, fallback float64) float64 {
|
|
if value := os.Getenv(key); value != "" {
|
|
if parsed, err := strconv.ParseFloat(value, 64); err == nil {
|
|
return parsed
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvStringSlice(key string, fallback []string) []string {
|
|
if value := os.Getenv(key); value != "" {
|
|
parts := strings.Split(value, ",")
|
|
result := make([]string, 0, len(parts))
|
|
for _, p := range parts {
|
|
if trimmed := strings.TrimSpace(p); trimmed != "" {
|
|
result = append(result, trimmed)
|
|
}
|
|
}
|
|
if len(result) > 0 {
|
|
return result
|
|
}
|
|
}
|
|
return fallback
|
|
}
|