Refactor configuration to use one source of truth for base URL - Add GetBaseURL() to config package: queries system_config table first, falls back to BASE_URL env var - Update SidecarHandler to accept config and use single base_url - Compute opds/api paths from base_url instead of storing separately: - OPDS: base_url + /opds - API: base_url + /api - Device Sync: base_url + /api/sync - Simplify OPDSHandler.getBaseURLs() to compute opds path - Remove need for separate opds_base_url and api_base_url columns Previously the system stored three separate URL config values that were usually the same domain with different paths. Now store only base_url and compute the paths, eliminating configuration redundancy.
98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
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
|
|
}
|