feat(render+admin): stop a render job (admin, any owner)
Build backend images / build content-svc (push) Failing after 1m0s
Build backend images / build file-svc (push) Failing after 1m3s
Build backend images / build gateway (push) Failing after 1m2s
Build backend images / build identity-svc (push) Failing after 1m20s
Build backend images / build notification-svc (push) Failing after 1m13s
Build backend images / build render-svc (push) Failing after 1m5s
Build backend images / build studio-svc (push) Failing after 1m0s

The render-queue cancel button used the owner-scoped /cancel (WHERE user_id=…),
so an admin couldn't stop another user's job. Added:
- render-svc: POST /v1/renders/:job_id/stop (admin-gated) → store.StopJob cancels
  any in-progress job regardless of owner and frees the assigned node
- admin: render-queue button now "توقف" → /api/admin/renders/{id}/stop (with confirm)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-03 01:39:33 +03:30
parent c7694a9bbf
commit 7f7feabb85
7 changed files with 53 additions and 6 deletions
@@ -131,6 +131,21 @@ func (h *RenderHandler) Cancel(c *gin.Context) {
})
}
// POST /v1/renders/:job_id/stop — admin: stop any user's in-progress job
func (h *RenderHandler) Stop(c *gin.Context) {
jobID, err := uuid.Parse(c.Param("job_id"))
if err != nil {
c.JSON(http.StatusBadRequest, models.APIError{Code: "bad_request", Message: "invalid job_id"})
return
}
stopped, err := h.store.StopJob(c.Request.Context(), jobID)
if err != nil {
c.JSON(http.StatusInternalServerError, models.APIError{Code: "internal_error", Message: err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"stopped": stopped})
}
// POST /v1/renders/:job_id/retry
func (h *RenderHandler) Retry(c *gin.Context) {
userID := middleware.GetUserID(c)