feat(api): add GET /api/artists/{id}/tracks handler
Wires ListArtistTracksForUser (Task 3 SQL) to a new handler that returns all quarantine-filtered tracks for an artist as a flat TrackRef list. 404 when the artist doesn't exist. Route registered in Mount(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -143,6 +143,46 @@ func (h *handlers) handleGetArtist(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusOK, detail)
|
||||
}
|
||||
|
||||
// handleGetArtistTracks implements GET /api/artists/{id}/tracks. Returns
|
||||
// every track the artist has across albums (per-user-quarantine filtered)
|
||||
// as a flat list. Used by ArtistCard's play affordance, which shuffles
|
||||
// client-side. 404 when the artist doesn't exist.
|
||||
func (h *handlers) handleGetArtistTracks(w http.ResponseWriter, r *http.Request) {
|
||||
id, ok := parseUUID(chi.URLParam(r, "id"))
|
||||
if !ok {
|
||||
writeErr(w, http.StatusBadRequest, "bad_request", "invalid artist id")
|
||||
return
|
||||
}
|
||||
user, ok := auth.UserFromContext(r.Context())
|
||||
if !ok {
|
||||
writeErr(w, http.StatusUnauthorized, "unauthorized", "authentication required")
|
||||
return
|
||||
}
|
||||
q := dbq.New(h.pool)
|
||||
if _, err := q.GetArtistByID(r.Context(), id); err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
writeErr(w, http.StatusNotFound, "not_found", "artist not found")
|
||||
return
|
||||
}
|
||||
h.logger.Error("api: get artist for tracks", "err", err)
|
||||
writeErr(w, http.StatusInternalServerError, "server_error", "lookup failed")
|
||||
return
|
||||
}
|
||||
rows, err := q.ListArtistTracksForUser(r.Context(), dbq.ListArtistTracksForUserParams{
|
||||
ArtistID: id, UserID: user.ID,
|
||||
})
|
||||
if err != nil {
|
||||
h.logger.Error("api: list artist tracks", "err", err)
|
||||
writeErr(w, http.StatusInternalServerError, "server_error", "lookup failed")
|
||||
return
|
||||
}
|
||||
out := make([]TrackRef, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
out = append(out, trackRefFrom(row.Track, row.AlbumTitle, row.ArtistName))
|
||||
}
|
||||
writeJSON(w, http.StatusOK, out)
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
Reference in New Issue
Block a user