package main import ( "log" "net/http" "os" "os/signal" "path/filepath" "strings" "syscall" _ "github.com/mattn/go-sqlite3" "pdf-wizard/handlers" "pdf-wizard/internal/db" ) func main() { dataDir := filepath.Join(".", "data") dbPath := filepath.Join(dataDir, "pdf_wizard.db") if err := os.MkdirAll(dataDir, 0755); err != nil { log.Fatalf("Creating data directory: %v", err) } dbConn, err := db.InitDB(dbPath) if err != nil { log.Fatalf("Initializing database: %v", err) } defer dbConn.Close() handler, err := handlers.NewHandler(dbConn, dataDir) if err != nil { log.Fatalf("Creating handler: %v", err) } http.HandleFunc("/api/pdf", handler.PDF) http.HandleFunc("/api/pdf/fill", handler.FillPDF) http.HandleFunc("/api/pdf/markdown", handler.Markdown) http.HandleFunc("/api/pdf/form", handler.RenderForm) http.HandleFunc("/api/pdf/extract", handler.ExtractContent) http.HandleFunc("/pdf", handler.ViewPage) admin := handlers.NewAdminHandler(dbConn, dataDir) http.HandleFunc("/admin", admin.AdminPage) http.HandleFunc("/admin/login", admin.LoginPage) http.HandleFunc("/admin/api/login", admin.Login) http.HandleFunc("/admin/api/logout", admin.Logout) http.HandleFunc("/admin/api/user", admin.UserPage) http.HandleFunc("/admin/api/orgs", admin.ListOrgs) http.HandleFunc("/admin/api/pdfs", admin.ListPDFs) http.HandleFunc("/admin/api/markdown", admin.GetMarkdown) http.HandleFunc("/admin/api/save", admin.SaveMarkdown) http.HandleFunc("/admin/api/preview", admin.PreviewForm) http.HandleFunc("/admin/api/versions", admin.ListMarkdownVersions) http.HandleFunc("/admin/api/versions/get", admin.GetMarkdownVersion) http.HandleFunc("/admin/api/prompt-versions", admin.ListPromptVersions) http.HandleFunc("/admin/api/prompt-versions/get", admin.GetPromptVersion) http.HandleFunc("/admin/api/prompts", admin.GetPrompts) http.HandleFunc("/admin/api/prompts/save", admin.SavePrompt) http.HandleFunc("/admin/api/prompts/toggle", admin.TogglePromptOverride) http.HandleFunc("/admin/api/prompts/delete", admin.DeletePrompt) http.HandleFunc("/admin/api/llm/reprocess", admin.ReprocessLLM) // Serve React app static assets http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("frontend/dist/assets")))) // Catch-all for React SPA routes http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { path := r.URL.Path if strings.HasPrefix(path, "/admin/") && !strings.HasPrefix(path, "/admin/api/") && path != "/admin/login" { admin.AdminPage(w, r) return } http.NotFound(w, r) }) http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) addr := ":8080" log.Printf("PDF Wizard API starting on http://localhost%s", addr) go func() { server := &http.Server{Addr: addr} if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("Server error: %v", err) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println("Shutting down...") }