feat(api): GET /api/artists with alpha/newest sort and paging

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-21 08:06:03 -04:00
parent f37fd782af
commit 8fb2f4e184
3 changed files with 268 additions and 2 deletions
+57 -2
View File
@@ -134,9 +134,64 @@ func (h *handlers) handleGetArtist(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, detail)
}
// handleListArtists is implemented in Task 9.
// handleListArtists implements GET /api/artists with two sort modes
// (alpha|newest) and enveloped pagination. album_count per artist is
// computed via an N+1 — acceptable at limit=200.
func (h *handlers) handleListArtists(w http.ResponseWriter, r *http.Request) {
writeErr(w, http.StatusNotImplemented, "not_implemented", "stub")
sort := r.URL.Query().Get("sort")
if sort == "" {
sort = "alpha"
}
if sort != "alpha" && sort != "newest" {
writeErr(w, http.StatusBadRequest, "bad_request", "sort must be alpha or newest")
return
}
limit, offset, err := parsePaging(r.URL.Query())
if err != nil {
writeErr(w, http.StatusBadRequest, "bad_request", err.Error())
return
}
q := dbq.New(h.pool)
var artists []dbq.Artist
switch sort {
case "newest":
artists, err = q.ListArtistsNewest(r.Context(), dbq.ListArtistsNewestParams{
Limit: int32(limit), Offset: int32(offset),
})
default: // alpha
artists, err = q.ListArtistsAlpha(r.Context(), dbq.ListArtistsAlphaParams{
Limit: int32(limit), Offset: int32(offset),
})
}
if err != nil {
h.logger.Error("api: list artists failed", "err", err)
writeErr(w, http.StatusInternalServerError, "server_error", "lookup failed")
return
}
total, err := q.CountArtists(r.Context())
if err != nil {
h.logger.Error("api: count artists failed", "err", err)
writeErr(w, http.StatusInternalServerError, "server_error", "count failed")
return
}
items := make([]ArtistRef, 0, len(artists))
for _, a := range artists {
albums, aerr := q.ListAlbumsByArtist(r.Context(), a.ID)
if aerr != nil {
h.logger.Error("api: list albums for artist failed", "err", aerr)
writeErr(w, http.StatusInternalServerError, "server_error", "lookup failed")
return
}
items = append(items, artistRefFrom(a, len(albums)))
}
writeJSON(w, http.StatusOK, Page[ArtistRef]{
Items: items,
Total: int(total),
Limit: limit,
Offset: offset,
})
}
// handleSearch is implemented in Task 10 (file: search.go).