package httpapi import ( "context" "net/http" "time" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "ai-workflow-skill/packages/orchd-runtime/internal/query" "ai-workflow-skill/packages/coord-core/store" ) type readService interface { ListRuns(ctx context.Context) ([]query.RunListItem, error) GetRunDetail(ctx context.Context, runID string) (query.RunDetail, error) ListRunTasks(ctx context.Context, runID string) ([]store.Task, error) ListBlockedTasks(ctx context.Context, runID string) ([]store.BlockedTask, error) GetThreadDetail(ctx context.Context, threadID string) (store.ThreadDetail, error) } func NewRouter(service readService) http.Handler { router := chi.NewRouter() router.Use(middleware.RequestID) router.Use(middleware.Recoverer) router.Use(middleware.Timeout(30 * time.Second)) router.Get("/health", func(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, map[string]any{ "status": "ok", }) }) router.Route("/api", func(r chi.Router) { r.Get("/runs", func(w http.ResponseWriter, r *http.Request) { runs, err := service.ListRuns(r.Context()) if err != nil { writeError(w, err) return } writeJSON(w, http.StatusOK, map[string]any{"runs": runs}) }) r.Get("/runs/{runID}", func(w http.ResponseWriter, r *http.Request) { runID := chi.URLParam(r, "runID") run, err := service.GetRunDetail(r.Context(), runID) if err != nil { writeError(w, err) return } writeJSON(w, http.StatusOK, map[string]any{"run": run}) }) r.Get("/runs/{runID}/tasks", func(w http.ResponseWriter, r *http.Request) { runID := chi.URLParam(r, "runID") tasks, err := service.ListRunTasks(r.Context(), runID) if err != nil { writeError(w, err) return } writeJSON(w, http.StatusOK, map[string]any{"tasks": tasks}) }) r.Get("/runs/{runID}/blocked", func(w http.ResponseWriter, r *http.Request) { runID := chi.URLParam(r, "runID") blocked, err := service.ListBlockedTasks(r.Context(), runID) if err != nil { writeError(w, err) return } writeJSON(w, http.StatusOK, map[string]any{"blocked": blocked}) }) r.Get("/threads/{threadID}", func(w http.ResponseWriter, r *http.Request) { threadID := chi.URLParam(r, "threadID") thread, err := service.GetThreadDetail(r.Context(), threadID) if err != nil { writeError(w, err) return } writeJSON(w, http.StatusOK, map[string]any{"thread": thread}) }) }) return router }