package server import ( "net/http" "forgejo.riotpiao.com/rock/homelab-frontend/internal/serviceadapter" ) // Router implements an HTTP handler that routes health endpoints, // ServiceAdapter X-Service requests, Temporal workflow endpoints, // and other requests to upstream handlers. type Router struct { healthChecker *HealthChecker dispatcher *serviceadapter.Dispatcher temporalHandler http.Handler upstreamHandler http.Handler } // NewRouter creates a new router with health endpoints. // Health endpoints (/healthz and /readyz) are handled locally. // X-Service requests are dispatched via ServiceAdapter CRD. // Temporal endpoints (/workflow*) are routed to temporalHandler. // All other paths are passed to the upstream handler. func NewRouter(healthChecker *HealthChecker, dispatcher *serviceadapter.Dispatcher, temporalHandler http.Handler, upstreamHandler http.Handler) *Router { return &Router{ healthChecker: healthChecker, dispatcher: dispatcher, temporalHandler: temporalHandler, upstreamHandler: upstreamHandler, } } // ServeHTTP implements http.Handler. // Priority order: // 1. /healthz and /readyz to health handlers // 2. X-Service header to ServiceAdapter dispatcher (phase 8) // 3. /workflow* to temporal handler // 4. All other paths to upstream handler (phase 0-7) func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { // Health endpoints first switch req.URL.Path { case "/healthz": LivenessHandler(r.healthChecker)(w, req) return case "/readyz": ReadinessHandler(r.healthChecker)(w, req) return } // X-Service (ServiceAdapter) routing - checked before path-based routing if req.Header.Get("X-Service") != "" { if r.dispatcher != nil { r.dispatcher.Dispatch(w, req) return } } // Workflow endpoints switch req.URL.Path { case "/workflow", "/workflow/health", "/workflow/metrics": r.temporalHandler.ServeHTTP(w, req) return } // Default: upstream handler (all other paths) r.upstreamHandler.ServeHTTP(w, req) }