package config import ( "os" "strconv" "time" ) // Config holds all runtime parameters for the count-api service. // All values are loaded from environment variables with safe defaults. type Config struct { Port string ModelPath string InferencePath string OCRDPI int OCRLang string OCRPoolSize int DBSCANEps float64 DBSCANMinSamples int SyncMaxFiles int MaxPDFSizeMB int PDFProcessTimeout time.Duration SyncProcessConcurrency int LogPipelineTiming bool } func Load() Config { return Config{ Port: getenv("PORT", "8080"), ModelPath: getenv("MODEL_PATH", "/app/models/model.onnx"), InferencePath: getenv("INFERENCE_CONFIG", "/app/models/inference.json"), OCRDPI: getenvInt("OCR_DPI", 300), OCRLang: getenv("OCR_LANG", "spa"), OCRPoolSize: getenvInt("OCR_POOL_SIZE", 0), DBSCANEps: getenvFloat("DBSCAN_EPS", 10), DBSCANMinSamples: getenvInt("DBSCAN_MIN_SAMPLES", 1), SyncMaxFiles: getenvInt("SYNC_MAX_FILES", 50), MaxPDFSizeMB: getenvInt("MAX_PDF_SIZE_MB", 20), PDFProcessTimeout: time.Duration(getenvInt("PDF_PROCESS_TIMEOUT_SEC", 120)) * time.Second, SyncProcessConcurrency: getenvInt("SYNC_PROCESS_CONCURRENCY", 0), LogPipelineTiming: getenvBool("LOG_PIPELINE_TIMING", false), } } func getenv(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback } func getenvInt(key string, fallback int) int { if v := os.Getenv(key); v != "" { if n, err := strconv.Atoi(v); err == nil { return n } } return fallback } func getenvFloat(key string, fallback float64) float64 { if v := os.Getenv(key); v != "" { if n, err := strconv.ParseFloat(v, 64); err == nil { return n } } return fallback } func getenvBool(key string, fallback bool) bool { if v := os.Getenv(key); v != "" { if b, err := strconv.ParseBool(v); err == nil { return b } } return fallback }