package main import ( "log" "net/http" "os" "erp_system/internal/database" "erp_system/internal/handlers" "erp_system/internal/middleware" "github.com/gorilla/sessions" ) func main() { // Initialize database db, err := database.Initialize("erp.db") if err != nil { log.Fatalf("Failed to initialize database: %v", err) } defer db.Close() // Session store sessionKey := os.Getenv("SESSION_KEY") if sessionKey == "" { sessionKey = "erp-system-dev-secret-key-change-in-prod" } store := sessions.NewCookieStore([]byte(sessionKey)) store.Options = &sessions.Options{ Path: "/", MaxAge: 86400, // 24 hours HttpOnly: true, } // Create handler context h := &handlers.Handler{ DB: db, Store: store, } // Auth middleware authMw := middleware.RequireAuth(store) // Router mux := http.NewServeMux() // Static/public routes mux.Handle("/resources/", http.StripPrefix("/resources/", http.FileServer(http.Dir("resources")))) mux.HandleFunc("GET /favicon.ico", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "resources/favicon.png") }) mux.HandleFunc("GET /login", h.LoginPage) mux.HandleFunc("POST /login", h.LoginSubmit) mux.HandleFunc("POST /logout", h.Logout) // Protected routes mux.Handle("GET /{$}", authMw(http.HandlerFunc(h.Dashboard))) // Customers mux.Handle("GET /customers", authMw(http.HandlerFunc(h.CustomerList))) mux.Handle("GET /customers/new", authMw(http.HandlerFunc(h.CustomerNew))) mux.Handle("POST /customers", authMw(http.HandlerFunc(h.CustomerCreate))) mux.Handle("GET /customers/{id}", authMw(http.HandlerFunc(h.CustomerDetail))) mux.Handle("GET /customers/{id}/edit", authMw(http.HandlerFunc(h.CustomerEdit))) mux.Handle("PUT /customers/{id}", authMw(http.HandlerFunc(h.CustomerUpdate))) mux.Handle("DELETE /customers/{id}", authMw(http.HandlerFunc(h.CustomerDelete))) // Orders mux.Handle("GET /orders", authMw(http.HandlerFunc(h.OrderList))) mux.Handle("GET /orders/new", authMw(http.HandlerFunc(h.OrderNew))) mux.Handle("POST /orders", authMw(http.HandlerFunc(h.OrderCreate))) mux.Handle("GET /orders/{id}", authMw(http.HandlerFunc(h.OrderDetail))) mux.Handle("GET /orders/{id}/edit", authMw(http.HandlerFunc(h.OrderEdit))) mux.Handle("PUT /orders/{id}", authMw(http.HandlerFunc(h.OrderUpdate))) mux.Handle("POST /orders/{id}/confirm", authMw(http.HandlerFunc(h.OrderConfirm))) mux.Handle("POST /orders/{id}/fulfill", authMw(http.HandlerFunc(h.OrderFulfill))) mux.Handle("POST /orders/{id}/cancel", authMw(http.HandlerFunc(h.OrderCancel))) mux.Handle("DELETE /orders/{id}", authMw(http.HandlerFunc(h.OrderDelete))) // Order lines (HTMX partials) mux.Handle("POST /orders/{id}/lines", authMw(http.HandlerFunc(h.OrderLineAdd))) mux.Handle("DELETE /orders/{id}/lines/{lineID}", authMw(http.HandlerFunc(h.OrderLineDelete))) // Invoices mux.Handle("GET /invoices", authMw(http.HandlerFunc(h.InvoiceList))) mux.Handle("GET /invoices/{id}", authMw(http.HandlerFunc(h.InvoiceDetail))) mux.Handle("POST /invoices/{id}/pay", authMw(http.HandlerFunc(h.InvoicePay))) // General Ledger mux.Handle("GET /ledger/accounts", authMw(http.HandlerFunc(h.ChartOfAccounts))) mux.Handle("GET /ledger/journal", authMw(http.HandlerFunc(h.JournalEntries))) mux.Handle("GET /ledger/journal/new", authMw(http.HandlerFunc(h.JournalEntryNew))) mux.Handle("POST /ledger/journal", authMw(http.HandlerFunc(h.JournalEntryCreate))) mux.Handle("GET /ledger/journal/{id}", authMw(http.HandlerFunc(h.JournalEntryDetail))) mux.Handle("GET /ledger/trial-balance", authMw(http.HandlerFunc(h.TrialBalance))) port := os.Getenv("PORT") if port == "" { port = "1337" } log.Printf("ERP System starting on http://localhost:%s", port) log.Printf("Default login: admin / admin123") if err := http.ListenAndServe(":"+port, mux); err != nil { log.Fatalf("Server failed: %v", err) } }