All checks were successful
Dev Build / build-test (pull_request) Successful in 2m23s
- Create repository/ package with pgx-backed CRUD for agents, sessions, tasks, projects - Define AgentRepo/SessionRepo/TaskRepo/ProjectRepo interfaces - Update handler to use repository interfaces instead of in-memory stores - Add SSE broker with GET /api/events endpoint (text/event-stream) - Add gateway client that polls OpenClaw for agent states - Add GATEWAY_URL and GATEWAY_POLL_INTERVAL config fields - Seed 5 demo agents (Otto, Rex, Dex, Hex, Pip) on empty DB - Update router to wire SSE broker - All 21 handler tests pass with mock repos
93 lines
3.3 KiB
Go
93 lines
3.3 KiB
Go
// Package router configures the chi router with all routes, middleware,
|
|
// and handler wiring for the Control Center API.
|
|
package router
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"time"
|
|
|
|
"code.cubecraftcreations.com/CubeCraft-Creations/Control-Center/go-backend/internal/db"
|
|
"code.cubecraftcreations.com/CubeCraft-Creations/Control-Center/go-backend/internal/handler"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/go-chi/chi/v5/middleware"
|
|
"github.com/go-chi/cors"
|
|
)
|
|
|
|
// Dependencies carries the handler, database pool, SSE broker, and CORS
|
|
// configuration into the router.
|
|
type Dependencies struct {
|
|
Handler *handler.Handler
|
|
Pool *db.Pool
|
|
CORSOrigin string
|
|
Broker *handler.Broker
|
|
}
|
|
|
|
// New creates a fully-configured chi router with all API routes mounted.
|
|
func New(deps *Dependencies) *chi.Mux {
|
|
r := chi.NewRouter()
|
|
|
|
// ── Global middleware ──────────────────────────────────────────────────
|
|
r.Use(middleware.RequestID)
|
|
r.Use(middleware.RealIP)
|
|
r.Use(middleware.Logger)
|
|
r.Use(middleware.Recoverer)
|
|
r.Use(middleware.Timeout(30 * time.Second))
|
|
|
|
// ── CORS ───────────────────────────────────────────────────────────────
|
|
corsOrigin := deps.CORSOrigin
|
|
if corsOrigin == "" {
|
|
corsOrigin = "*"
|
|
}
|
|
r.Use(cors.Handler(cors.Options{
|
|
AllowedOrigins: []string{corsOrigin},
|
|
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
|
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type"},
|
|
ExposedHeaders: []string{"Link", "X-Total-Count"},
|
|
AllowCredentials: false,
|
|
MaxAge: 300,
|
|
}))
|
|
|
|
// ── Health check (with DB connectivity probe) ──────────────────────────
|
|
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
status := "ok"
|
|
if deps.Pool != nil {
|
|
ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second)
|
|
defer cancel()
|
|
if err := deps.Pool.Ping(ctx); err != nil {
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
status = "db_unhealthy"
|
|
}
|
|
}
|
|
w.Write([]byte(`{"status":"` + status + `"}`))
|
|
})
|
|
|
|
// ── API v1 routes ──────────────────────────────────────────────────────
|
|
r.Route("/api", func(api chi.Router) {
|
|
// Agents CRUD
|
|
api.Route("/agents", func(agents chi.Router) {
|
|
agents.Get("/", deps.Handler.ListAgents) // GET /api/agents
|
|
agents.Post("/", deps.Handler.CreateAgent) // POST /api/agents
|
|
agents.Get("/{id}", deps.Handler.GetAgent) // GET /api/agents/{id}
|
|
agents.Put("/{id}", deps.Handler.UpdateAgent) // PUT /api/agents/{id}
|
|
agents.Delete("/{id}", deps.Handler.DeleteAgent) // DELETE /api/agents/{id}
|
|
agents.Get("/{id}/history", deps.Handler.AgentHistory) // GET /api/agents/{id}/history
|
|
})
|
|
|
|
// Sessions
|
|
api.Get("/sessions", deps.Handler.ListSessions)
|
|
|
|
// Tasks
|
|
api.Get("/tasks", deps.Handler.ListTasks)
|
|
|
|
// Projects
|
|
api.Get("/projects", deps.Handler.ListProjects)
|
|
|
|
// SSE event stream
|
|
api.Get("/events", deps.Broker.ServeHTTP)
|
|
})
|
|
|
|
return r
|
|
}
|