feat(scanner): POST /api/scanner/cancel/:jobId (admin)
Cancels a pending or running scan job. Responses: 200 with the job id and status on acceptance, 404 for unknown jobs, 409 for jobs already in a terminal state (completed/failed/cancelled). Additive route in the existing admin scanner group; no contract pins affected.
This commit is contained in:
1 parent
30ecdd4bf3
commit
5b81e19f2f
2 files changed
+24
No files matched your search
@@ -3,6 +3,7 @@ package handlers
|
||||
import (
|
||||
"bookhoard/internal/services"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
@@ -209,6 +210,28 @@ func (h *Handler) GetScanSummary(c *echo.Context) error {
|
||||
})
|
||||
}
|
||||
|
||||
// CancelScan handles POST /api/scanner/cancel/:jobId (admin): requests
|
||||
// cancellation of a pending or running scan job. Cancellation is
|
||||
// cooperative — the file currently being processed finishes, the walk
|
||||
// stops at its next context check, and the archive pass is skipped so
|
||||
// unvisited files are never treated as missing.
|
||||
func (h *Handler) CancelScan(c *echo.Context) error {
|
||||
jobID := c.Param("jobId")
|
||||
|
||||
if err := h.worker.CancelJob(jobID); err != nil {
|
||||
if errors.Is(err, services.ErrJobNotFound) {
|
||||
return c.JSON(http.StatusNotFound, map[string]string{"error": "job not found"})
|
||||
}
|
||||
return c.JSON(http.StatusConflict, map[string]string{"error": err.Error()})
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, map[string]interface{}{
|
||||
"message": "scan cancellation requested",
|
||||
"job_id": jobID,
|
||||
"status": "cancelled",
|
||||
})
|
||||
}
|
||||
|
||||
// StartWatchModeForLibrary starts watching a specific library's folders
|
||||
func (h *Handler) StartWatchModeForLibrary(ctx context.Context, libraryID pgtype.UUID, adminID pgtype.UUID) error {
|
||||
h.mu.Lock()
|
||||
|
||||
@@ -17,6 +17,7 @@ func registerScannerRoutes(protected, admin *echo.Group, h *handlers.Handler) {
|
||||
admin.POST("/scanner/scan", h.ScanLibrary)
|
||||
admin.POST("/scanner/start", h.StartScanner)
|
||||
admin.POST("/scanner/stop", h.StopScanner)
|
||||
admin.POST("/scanner/cancel/:jobId", h.CancelScan)
|
||||
admin.GET("/scanner/status/:jobId", h.GetScanStatus)
|
||||
admin.GET("/scanner/active", h.GetActiveScans)
|
||||
|
||||
|
||||
Reference in new issue
Block a user