package handlers import ( "context" "net/http" "github.com/go-chi/chi/v5" "github.com/orchard9/rdev/internal/sdlc" "github.com/orchard9/rdev/internal/validate" "github.com/orchard9/rdev/pkg/api" ) // AddTaskRequest is the request body for POST /projects/{id}/sdlc/features/{slug}/tasks. type AddTaskRequest struct { Title string `json:"title"` } // ListTasks returns all tasks for a feature. // GET /projects/{id}/sdlc/features/{slug}/tasks func (h *SDLCHandler) ListTasks(w http.ResponseWriter, r *http.Request) { projectID := chi.URLParam(r, "id") slug := chi.URLParam(r, "slug") ctx, cancel := context.WithTimeout(r.Context(), TimeoutStandard) defer cancel() tasks, err := h.sdlcService.ListTasks(ctx, projectID, slug) if err != nil { writeSDLCError(w, r, err) return } if tasks == nil { tasks = []sdlc.Task{} } api.WriteSuccess(w, r, tasks) } // AddTask adds a new task to a feature. // POST /projects/{id}/sdlc/features/{slug}/tasks func (h *SDLCHandler) AddTask(w http.ResponseWriter, r *http.Request) { projectID := chi.URLParam(r, "id") slug := chi.URLParam(r, "slug") var req AddTaskRequest if err := api.DecodeJSON(r, &req); err != nil { api.WriteBadRequest(w, r, "invalid request body") return } v := validate.New() v.Required(req.Title, "title") if err := v.Error(); err != nil { api.WriteBadRequest(w, r, err.Error()) return } ctx, cancel := context.WithTimeout(r.Context(), TimeoutHeavyWrite) defer cancel() task, err := h.sdlcService.AddTask(ctx, projectID, slug, req.Title) if err != nil { writeSDLCError(w, r, err) return } api.WriteCreated(w, r, task) } // StartTask marks a task as in-progress. // POST /projects/{id}/sdlc/features/{slug}/tasks/{taskId}/start func (h *SDLCHandler) StartTask(w http.ResponseWriter, r *http.Request) { projectID := chi.URLParam(r, "id") slug := chi.URLParam(r, "slug") taskID := chi.URLParam(r, "taskId") ctx, cancel := context.WithTimeout(r.Context(), TimeoutHeavyWrite) defer cancel() if err := h.sdlcService.StartTask(ctx, projectID, slug, taskID); err != nil { writeSDLCError(w, r, err) return } api.WriteSuccess(w, r, map[string]any{ "feature": slug, "task_id": taskID, "status": "in_progress", }) } // CompleteTask marks a task as complete. // POST /projects/{id}/sdlc/features/{slug}/tasks/{taskId}/complete func (h *SDLCHandler) CompleteTask(w http.ResponseWriter, r *http.Request) { projectID := chi.URLParam(r, "id") slug := chi.URLParam(r, "slug") taskID := chi.URLParam(r, "taskId") ctx, cancel := context.WithTimeout(r.Context(), TimeoutHeavyWrite) defer cancel() if err := h.sdlcService.CompleteTask(ctx, projectID, slug, taskID); err != nil { writeSDLCError(w, r, err) return } api.WriteSuccess(w, r, map[string]any{ "feature": slug, "task_id": taskID, "status": "complete", }) } // BlockTask marks a task as blocked. // POST /projects/{id}/sdlc/features/{slug}/tasks/{taskId}/block func (h *SDLCHandler) BlockTask(w http.ResponseWriter, r *http.Request) { projectID := chi.URLParam(r, "id") slug := chi.URLParam(r, "slug") taskID := chi.URLParam(r, "taskId") ctx, cancel := context.WithTimeout(r.Context(), TimeoutHeavyWrite) defer cancel() if err := h.sdlcService.BlockTask(ctx, projectID, slug, taskID); err != nil { writeSDLCError(w, r, err) return } api.WriteSuccess(w, r, map[string]any{ "feature": slug, "task_id": taskID, "status": "blocked", }) }