diff --git a/controller/internal/api/router.go b/controller/internal/api/router.go index dbf13a4..878fe12 100644 --- a/controller/internal/api/router.go +++ b/controller/internal/api/router.go @@ -112,6 +112,12 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { case path == "/stacks/rescan" && req.Method == http.MethodPost: r.rescanStacks(w, req) + // F4: /api/stacks/rescan with a non-POST method must be a clear 405, not fall through to the + // GET /stacks/{name} lookup below (which returned the misleading "stack not found: rescan"). + case path == "/stacks/rescan": + w.Header().Set("Allow", http.MethodPost) + writeJSON(w, http.StatusMethodNotAllowed, apiResponse{OK: false, Error: "method not allowed: use POST /api/stacks/rescan"}) + // GET /api/stacks/{name} case strings.HasPrefix(path, "/stacks/") && req.Method == http.MethodGet && !hasSubpath(path, "/stacks/"): r.getStack(w, req, trimSegment(path, "/stacks/")) @@ -378,11 +384,15 @@ func (r *Router) deployStack(w http.ResponseWriter, req *http.Request, name stri return } - resp := apiResponse{OK: true, Message: "Stack " + name + " deployed"} + // F6: the deploy runs asynchronously (compose pull/up + health happen after this returns; the UI + // polls GET /api/stacks/{name}). The old "Stack X deployed" message asserted completion before it + // was true — misleading for API/script consumers. Report that the deploy STARTED, not that it + // finished. 202 Accepted reflects "accepted, processing"; ok:true is preserved for the UI. + resp := apiResponse{OK: true, Message: "Telepítés elindítva – az állapot a kártyán követhető"} if warning != "" { resp.Data = map[string]string{"warning": warning} } - writeJSON(w, http.StatusOK, resp) + writeJSON(w, http.StatusAccepted, resp) // Push app deployed event to Hub if r.notifier != nil {