package httpserver import ( "encoding/json" "errors" "fmt" "net/http" "strings" "github.com/toki/oto/services/core/internal/cicdstate" otopb "github.com/toki/oto/services/core/oto" ) func handleCreateJob(store *cicdstate.Store, dispatcher runnerControlDispatcher) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req struct { ID string `json:"id"` Name string `json:"name"` RunRequest *otopb.RunRequest `json:"run_request"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeResponse(w, http.StatusBadRequest, map[string]string{"error": "invalid request body"}) return } if req.ID == "" || req.Name == "" { writeResponse(w, http.StatusBadRequest, map[string]string{"error": "id and name are required"}) return } job, err := store.CreateJob(req.ID, req.Name, runRequestFromJSON(req.RunRequest)) if err != nil { writeResponse(w, http.StatusConflict, map[string]string{"error": err.Error()}) return } if dispatcher != nil { go dispatcher.DispatchQueuedJobs() } writeResponse(w, http.StatusCreated, jobToJSON(job)) } } func handleGetJob(store *cicdstate.Store) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { jobID := r.PathValue("id") if jobID == "" { parts := strings.Split(r.URL.Path, "/") if len(parts) >= 5 { jobID = parts[4] } } if jobID == "" { writeResponse(w, http.StatusBadRequest, map[string]string{"error": "missing job id"}) return } job, err := store.GetJob(jobID) if err != nil { if errors.Is(err, fmt.Errorf("job not found: %s", jobID)) || err.Error() == "job not found: "+jobID { writeResponse(w, http.StatusNotFound, map[string]string{"error": "job not found"}) return } writeResponse(w, http.StatusInternalServerError, map[string]string{"error": "internal error"}) return } writeResponse(w, http.StatusOK, jobToJSON(job)) } } func handleCreateExecution(store *cicdstate.Store) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { jobID := r.PathValue("id") if jobID == "" { parts := strings.Split(r.URL.Path, "/") if len(parts) >= 5 { jobID = parts[4] } } if jobID == "" { writeResponse(w, http.StatusBadRequest, map[string]string{"error": "missing job id"}) return } var req struct { ID string `json:"id"` } _ = json.NewDecoder(r.Body).Decode(&req) if req.ID == "" { writeResponse(w, http.StatusBadRequest, map[string]string{"error": "execution id is required"}) return } exec, err := store.CreateExecution(jobID, req.ID) if err != nil { writeResponse(w, http.StatusBadRequest, map[string]string{"error": err.Error()}) return } writeResponse(w, http.StatusCreated, execToJSON(exec)) } }