package api import ( "context" "errors" "net/http" "github.com/go-chi/chi/v5" "github.com/jackc/pgx/v5" "git.fabledsword.com/bvandeusen/minstrel/internal/coverart" "git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq" ) type adminCoverRefetchResp struct { AlbumID string `json:"album_id"` CoverArtPath *string `json:"cover_art_path"` CoverArtSource *string `json:"cover_art_source"` } // handleAdminAlbumRefetchCover implements POST /api/admin/albums/{id}/cover/refetch. // Synchronously clears + re-runs the enricher for one album. func (h *handlers) handleAdminAlbumRefetchCover(w http.ResponseWriter, r *http.Request) { albumID, ok := parseUUID(chi.URLParam(r, "id")) if !ok { writeErr(w, http.StatusBadRequest, "bad_request", "invalid album id") return } if err := h.coverart.RetryAlbum(r.Context(), albumID); err != nil { if errors.Is(err, coverart.ErrNotFound) || errors.Is(err, pgx.ErrNoRows) { writeErr(w, http.StatusNotFound, "not_found", "album not found") return } h.logger.Error("admin: cover refetch failed", "err", err) writeErr(w, http.StatusInternalServerError, "server_error", "refetch failed") return } row, err := dbq.New(h.pool).GetAlbumWithFirstTrackPath(r.Context(), albumID) if err != nil { h.logger.Error("admin: post-refetch read failed", "err", err) writeErr(w, http.StatusInternalServerError, "server_error", "read failed") return } writeJSON(w, http.StatusOK, adminCoverRefetchResp{ AlbumID: uuidToString(albumID), CoverArtPath: row.CoverArtPath, CoverArtSource: row.CoverArtSource, }) } type adminBulkRefetchResp struct { Queued int `json:"queued"` } // handleAdminBulkRefetchCovers implements POST /api/admin/covers/refetch-missing. // Returns immediately; actual drain runs in a background goroutine bounded by // the configured backfill cap. func (h *handlers) handleAdminBulkRefetchCovers(w http.ResponseWriter, _ *http.Request) { cap := h.coverArtBackfillCap go func() { bgCtx := context.Background() if _, err := h.coverart.EnrichRetryMissing(bgCtx, cap); err != nil { h.logger.Warn("admin: bulk cover refetch failed", "err", err) } }() writeJSON(w, http.StatusOK, adminBulkRefetchResp{Queued: cap}) }