package main import ( "context" "log" "os" "os/signal" "syscall" "github.com/pys/pdf-count/internal/api" "github.com/pys/pdf-count/internal/config" "github.com/pys/pdf-count/internal/model" "github.com/pys/pdf-count/internal/ocr" ) func main() { cfg := config.Load() ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer cancel() predictor, err := model.NewPredictor(cfg.ModelPath, cfg.InferencePath) if err != nil { log.Printf("WARN: modelo ML no disponible (%v) — usando heuristica de conteo", err) predictor = nil } else { defer predictor.Close() log.Printf("modelo ONNX cargado: %s (features=%d, threshold=%.2f)", cfg.ModelPath, predictor.FeatureCount(), predictor.Threshold()) } poolSize := cfg.OCRPoolSize if poolSize <= 0 { poolSize = 4 } ocrEngine, err := ocr.NewEngine(cfg.OCRLang, poolSize) if err != nil { log.Fatalf("ocr: %v", err) } defer ocrEngine.Close() openAPIPath := os.Getenv("OPENAPI_PATH") if openAPIPath == "" { openAPIPath = "api/openapi.yaml" } srv := api.NewServer(cfg, predictor, ocrEngine, api.LoadOpenAPI(openAPIPath)) addr := ":" + cfg.Port log.Printf("count-api escuchando en %s", addr) if err := api.ListenAndServe(ctx, addr, srv.Router()); err != nil { log.Fatalf("server: %v", err) } }