package main import ( "context" "errors" "log" "net/http" "os" "os/signal" "syscall" "time" "primaya-api/cpone-middleware/internal/config" "primaya-api/cpone-middleware/internal/databaseconfig" apphttp "primaya-api/cpone-middleware/internal/http" ) func main() { cfg, err := config.Load(".env") if err != nil { log.Fatalf("load config: %v", err) } bootstrapCtx, bootstrapCancel := context.WithTimeout(context.Background(), 20*time.Second) resolver, err := databaseconfig.NewStaticResolver(bootstrapCtx, cfg.RSCode, databaseconfig.Setting{ Host: cfg.HISDBHost, Port: cfg.HISDBPort, Database: cfg.HISDBDatabase, Username: cfg.HISDBUsername, Password: cfg.HISDBPassword, }, databaseconfig.PoolConfig{ MaxOpenConns: cfg.DBMaxOpenConns, MaxIdleConns: cfg.DBMaxIdleConns, ConnMaxLifetime: cfg.DBConnMaxLifetime, }) bootstrapCancel() if err != nil { log.Fatalf("load database HIS: %v", err) } defer resolver.Close() handler := apphttp.NewDynamicHandler(cfg.RSCode, cfg.DepartmentID) protected := func(handler http.Handler) http.Handler { return apphttp.BearerAuth(cfg.BearerToken, apphttp.SelectDatabase(resolver, handler)) } mux := http.NewServeMux() mux.Handle("POST /api/cpone/paket", protected(http.HandlerFunc(handler.CreatePaket))) mux.Handle("GET /api/cpone/paket", protected(http.HandlerFunc(handler.ListPaket))) mux.Handle("GET /api/cpone/paket/{id}", protected(http.HandlerFunc(handler.GetPaket))) mux.Handle("GET /api/cpone/layanan", protected(http.HandlerFunc(handler.ListLayanan))) mux.Handle("GET /api/cpone/perusahaan", protected(http.HandlerFunc(handler.ListPerusahaan))) mux.Handle("GET /api/cpone/perusahaan/{id}", protected(http.HandlerFunc(handler.GetPerusahaan))) mux.Handle("GET /api/cpone/perusahaan/{id}/group-tarif", protected(http.HandlerFunc(handler.GetPerusahaanGroupTarif))) mux.Handle("GET /api/cpone/doctors", protected(http.HandlerFunc(handler.ListDokter))) // Backward-compatible route matching the source Primaya API. mux.Handle("GET /api/doctors", protected(http.HandlerFunc(handler.ListDokter))) mux.Handle("GET /api/cpone/tarif-kerjasama", protected(http.HandlerFunc(handler.ListTarifKerjasama))) mux.Handle("GET /api/cpone/tarif-kerjasama/{id}", protected(http.HandlerFunc(handler.GetTarifKerjasama))) mux.Handle("GET /api/cpone/periode-tarif", protected(http.HandlerFunc(handler.ListPeriodeTarif))) mux.Handle("GET /api/cpone/periode-tarif/{periodeTarifID}", protected(http.HandlerFunc(handler.ListPeriodeTarifLayanan))) mux.Handle("GET /api/cpone/layanan-mapping-harga", protected(http.HandlerFunc(handler.MappingHarga))) mux.Handle("POST /api/cpone/patients/medrec", protected(http.HandlerFunc(handler.StoreMedrec))) mux.Handle("POST /api/cpone/patients/registration", protected(http.HandlerFunc(handler.RegisterPatient))) mux.Handle("POST /api/cpone/patients/lab-registration", protected(http.HandlerFunc(handler.RegisterLab))) mux.Handle("POST /api/cpone/patients/lab-registration/{regId}/services", protected(http.HandlerFunc(handler.AddLabServices))) mux.Handle("POST /api/cpone/patients/lab-registration/{regId}/packages", protected(http.HandlerFunc(handler.AddLabPackage))) mux.Handle("GET /api/cpone/patients/lab-results/{labNumber}", protected(http.HandlerFunc(handler.GetLabResult))) mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"success":true,"message":"ok","data":null}`)) }) server := &http.Server{ Addr: cfg.Addr(), Handler: mux, ReadHeaderTimeout: 10 * time.Second, } go func() { log.Printf("cpone middleware listening on %s", cfg.Addr()) if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { log.Fatalf("listen: %v", err) } }() stop := make(chan os.Signal, 1) signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM) <-stop shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second) defer shutdownCancel() if err := server.Shutdown(shutdownCtx); err != nil { log.Fatalf("shutdown: %v", err) } }