package daemon import ( "context" "log/slog" "net/http" "strconv" "time" "git.cloudinit.dev/coreci/orca/internal/model" "git.cloudinit.dev/coreci/orca/internal/store" ) // handleTasksCollection handles /v1/tasks (GET only). // Optional query param: ?job_id= to filter by job. // Optional: ?limit= (default 100, max 1000). func (s *Server) handleTasksCollection(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { writeError(w, http.StatusMethodNotAllowed, "method not allowed") return } ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) defer cancel() jobID := r.URL.Query().Get("job_id") if jobID != "" { if err := validateID(jobID); err != nil { writeError(w, http.StatusBadRequest, err.Error()) return } } limit := 100 if v := r.URL.Query().Get("limit"); v != "" { n, err := strconv.Atoi(v) if err != nil || n <= 0 { writeError(w, http.StatusBadRequest, "invalid limit") return } if n > 1000 { n = 1000 } limit = n } repo := store.NewTaskRepo(s.db) var tasks []*model.Task var err error if jobID != "" { tasks, err = repo.ListByJob(ctx, jobID) } else { tasks, err = repo.ListRecent(ctx, limit) } if err != nil { s.log.Error("list tasks", slog.String("component", "daemon"), slog.String("job_id", jobID), slog.String("error", err.Error())) writeError(w, http.StatusInternalServerError, "failed to list tasks") return } if tasks == nil { tasks = []*model.Task{} } writeJSON(w, http.StatusOK, map[string]any{"tasks": tasks, "count": len(tasks)}) }