diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-04-04 09:30:13 +0000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-04-04 09:30:13 +0000 |
| commit | 940a5bab031bfe81cea9c90d64e6ebc804c366f9 (patch) | |
| tree | 34f41c4675f0e238c5acd9665790d256ea39a041 /internal/api/stories.go | |
| parent | 2917c580ae3eab093e9e655ccdf210030b7b9d1f (diff) | |
feat: story ship gate — explicit POST /api/stories/{id}/ship; remove auto-deploy
- checkStoryCompletion now guards against re-running on already-SHIPPABLE stories
and no longer auto-triggers triggerStoryDeploy on completion
- New Pool.ShipStory method validates SHIPPABLE state then fires triggerStoryDeploy
- POST /api/stories/{id}/ship route registered and handleShipStory handler added
- Two new tests: 202 for SHIPPABLE story, 409 for non-SHIPPABLE story
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/api/stories.go')
| -rw-r--r-- | internal/api/stories.go | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/internal/api/stories.go b/internal/api/stories.go index 629ea7a..1743dbe 100644 --- a/internal/api/stories.go +++ b/internal/api/stories.go @@ -322,6 +322,17 @@ func (s *Server) handleApproveStory(w http.ResponseWriter, r *http.Request) { }) } +// handleShipStory triggers the merge + deploy for a SHIPPABLE story. +// POST /api/stories/{id}/ship +func (s *Server) handleShipStory(w http.ResponseWriter, r *http.Request) { + id := r.PathValue("id") + if err := s.pool.ShipStory(r.Context(), id); err != nil { + writeJSON(w, http.StatusConflict, map[string]string{"error": err.Error()}) + return + } + writeJSON(w, http.StatusAccepted, map[string]string{"message": "story shipping initiated", "story_id": id}) +} + // handleStoryDeploymentStatus aggregates the deployment status across all tasks in a story. // GET /api/stories/{id}/deployment-status func (s *Server) handleStoryDeploymentStatus(w http.ResponseWriter, r *http.Request) { |
