From 7a5de6fa1ba4bbb864a42fa8c790894dfc943b85 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 10 Apr 2026 23:15:53 +0000 Subject: [PATCH] Exclude deleted, unavailable, and deactivated-user tracks from listening history The history endpoint was returning tracks that had been removed (is_delete), made unavailable (is_available=false), or owned by deactivated users. Add filters consistent with other track-listing endpoints. https://claude.ai/code/session_01PZcVKSnX4KGMcL9zmQvsC9 --- api/v1_users_history.go | 6 ++- api/v1_users_history_test.go | 90 ++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/api/v1_users_history.go b/api/v1_users_history.go index 15af83a3..51a9b434 100644 --- a/api/v1_users_history.go +++ b/api/v1_users_history.go @@ -62,7 +62,11 @@ func (app *ApiServer) v1UsersHistory(c *fiber.Ctx) error { class = "track_activity_full" } - filters := []string{} + filters := []string{ + "tracks.is_delete = false", + "tracks.is_available = true", + "users.is_deactivated = false", + } if params.Query != "" { filters = append(filters, "tracks.title ILIKE '%' || @query || '%' OR users.name ILIKE '%' || @query || '%'") } diff --git a/api/v1_users_history_test.go b/api/v1_users_history_test.go index 7f458b7b..995136b0 100644 --- a/api/v1_users_history_test.go +++ b/api/v1_users_history_test.go @@ -67,6 +67,96 @@ func TestUserListeningHistory(t *testing.T) { }) } +func TestUserListeningHistoryExcludesRemovedTracks(t *testing.T) { + app := emptyTestApp(t) + + fixtures := database.FixtureMap{ + "users": []map[string]any{ + { + "user_id": 1, + "handle": "active_user", + }, + { + "user_id": 2, + "handle": "listener", + "wallet": "0x7d273271690538cf855e5b3002a0dd8c154bb060", + }, + { + "user_id": 3, + "handle": "deactivated_user", + "is_deactivated": true, + }, + }, + "tracks": []map[string]any{ + { + "track_id": 1, + "title": "Active Track", + "owner_id": 1, + "is_delete": false, + "created_at": parseTime(t, "2024-01-01"), + }, + { + "track_id": 2, + "title": "Deleted Track", + "owner_id": 1, + "is_delete": true, + "created_at": parseTime(t, "2024-01-01"), + }, + { + "track_id": 3, + "title": "Unavailable Track", + "owner_id": 1, + "is_available": false, + "created_at": parseTime(t, "2024-01-01"), + }, + { + "track_id": 4, + "title": "Deactivated User Track", + "owner_id": 3, + "created_at": parseTime(t, "2024-01-01"), + }, + }, + "user_listening_history": []map[string]any{ + { + "user_id": 2, + "listening_history": []map[string]any{ + { + "track_id": 1, + "play_count": 1, + "timestamp": parseTime(t, "2024-01-04"), + }, + { + "track_id": 2, + "play_count": 1, + "timestamp": parseTime(t, "2024-01-03"), + }, + { + "track_id": 3, + "play_count": 1, + "timestamp": parseTime(t, "2024-01-02"), + }, + { + "track_id": 4, + "play_count": 1, + "timestamp": parseTime(t, "2024-01-01"), + }, + }, + }, + }, + } + + database.Seed(app.pool.Replicas[0], fixtures) + listenerId := trashid.MustEncodeHashID(2) + + // Only the active track should appear; deleted, unavailable, and deactivated-user tracks are excluded + status, body := testGetWithWallet(t, app, "/v1/full/users/"+listenerId+"/history/tracks?user_id="+listenerId, "0x7d273271690538cf855e5b3002a0dd8c154bb060") + assert.Equal(t, 200, status) + jsonAssert(t, body, map[string]any{ + "data.#": 1, + "data.0.item.title": "Active Track", + }) +} + func TestUserListeningHistoryUnlisted(t *testing.T) { app := emptyTestApp(t)