package api import ( "net/http" "strings" "github.com/fmartingr/ccrm/server/internal/db" "github.com/fmartingr/ccrm/server/internal/ws" ) // NewRouter creates the HTTP router with all API endpoints. func NewRouter(database *db.DB, hub *ws.Hub, daemonAPIKey, dashboardToken string) http.Handler { mux := http.NewServeMux() sessionsHandler := &SessionsHandler{DB: database} promptHandler := &PromptHandler{Hub: hub} // WebSocket endpoints (no additional auth middleware — handled in WS handlers) mux.HandleFunc("/ws/daemon", ws.HandleDaemonWS(hub, daemonAPIKey)) mux.HandleFunc("/ws/dashboard", ws.HandleDashboardWS(hub, dashboardToken)) // API endpoints — wrapped with auth middleware authMw := DashboardAuth(dashboardToken) // Sessions mux.Handle("/api/sessions", authMw(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: sessionsHandler.List(w, r) default: http.Error(w, "method not allowed", http.StatusMethodNotAllowed) } }))) mux.Handle("/api/sessions/", authMw(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { path := strings.TrimPrefix(r.URL.Path, "/api/sessions/") switch { case strings.HasSuffix(path, "/events"): if r.Method == http.MethodGet { sessionsHandler.ListEvents(w, r) } else { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) } case strings.HasSuffix(path, "/prompt"): if r.Method == http.MethodPost { promptHandler.Send(w, r) } else { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) } default: if r.Method == http.MethodGet { sessionsHandler.Get(w, r) } else { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) } } }))) // CORS middleware for development return corsMiddleware(mux) } func corsMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") if r.Method == http.MethodOptions { w.WriteHeader(http.StatusOK) return } next.ServeHTTP(w, r) }) }