From 6f75d0e4a8880401cec1003977e2e77930c43e3e Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Thu, 22 Jan 2026 11:34:49 -0500 Subject: [PATCH] fix: prevent Spotify social deletion when updating multiple platforms Bug: When AI calls update_artist_socials with both YouTube AND existing Spotify URLs, the Spotify social gets deleted but NOT re-inserted. Root cause: The accountSocials array is fetched once at the start of updateArtistSocials and becomes stale after deleting a social. The check on lines 52-54 used this stale array to determine if the account_social relationship exists, incorrectly skipping the insert. Fix: Always insert the account_social relationship after processing a platform, since we know we deleted the old one (if it existed). Co-Authored-By: Claude Opus 4.5 --- .../__tests__/updateArtistSocials.test.ts | 45 +++++++++++++++++++ lib/artist/updateArtistSocials.ts | 11 ++--- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/lib/artist/__tests__/updateArtistSocials.test.ts b/lib/artist/__tests__/updateArtistSocials.test.ts index 2b43f179..6bc8447f 100644 --- a/lib/artist/__tests__/updateArtistSocials.test.ts +++ b/lib/artist/__tests__/updateArtistSocials.test.ts @@ -126,4 +126,49 @@ describe("updateArtistSocials", () => { expect(mockInsertSocials).not.toHaveBeenCalled(); expect(mockInsertAccountSocial).toHaveBeenCalledWith(artistId, "existing-db-social"); }); + + it("re-inserts Spotify relationship when updating both YouTube and Spotify URLs", async () => { + // BUG: When AI passes both YouTube AND existing Spotify URL, the Spotify + // social gets deleted but NOT re-inserted due to stale accountSocials check + const existingSpotifySocial = { + id: "account-social-spotify", + account_id: artistId, + social_id: "social-spotify-1", + social: { + id: "social-spotify-1", + username: "artistname", + profile_url: "open.spotify.com/artist/0TnOYISbd1XYRBk9myaseg", + }, + }; + + const existingSpotifySocialRecord = { + id: "social-spotify-1", + username: "artistname", + profile_url: "open.spotify.com/artist/0TnOYISbd1XYRBk9myaseg", + }; + + mockSelectAccountSocials.mockResolvedValue([existingSpotifySocial]); + mockSelectSocials.mockImplementation(({ profile_url }) => { + if (profile_url === "open.spotify.com/artist/0TnOYISbd1XYRBk9myaseg") { + return Promise.resolve([existingSpotifySocialRecord]); + } + return Promise.resolve([]); + }); + mockInsertSocials.mockResolvedValue([ + { id: "new-youtube-social", username: "artistchannel", profile_url: "youtube.com/@artistchannel" }, + ]); + + // Update both YouTube AND Spotify (same Spotify URL as existing) + await updateArtistSocials(artistId, { + YOUTUBE: "https://youtube.com/@artistchannel", + SPOTIFY: "https://open.spotify.com/artist/0TnOYISbd1XYRBk9myaseg", + }); + + // Should delete existing Spotify (to replace it) + expect(mockDeleteAccountSocial).toHaveBeenCalledWith(artistId, "social-spotify-1"); + // CRITICAL: Should re-insert the Spotify relationship after deleting it + expect(mockInsertAccountSocial).toHaveBeenCalledWith(artistId, "social-spotify-1"); + // Should also insert YouTube + expect(mockInsertAccountSocial).toHaveBeenCalledWith(artistId, "new-youtube-social"); + }); }); diff --git a/lib/artist/updateArtistSocials.ts b/lib/artist/updateArtistSocials.ts index e579e7c4..7605745f 100644 --- a/lib/artist/updateArtistSocials.ts +++ b/lib/artist/updateArtistSocials.ts @@ -48,13 +48,10 @@ export async function updateArtistSocials( // Insert new social if (social) { - // Social already exists, check if account_social relationship exists - const existing = (accountSocials || []).find( - (as: AccountSocialWithSocial) => as.social_id === social.id, - ); - if (!existing) { - await insertAccountSocial(artistId, social.id); - } + // Always insert the account_social relationship since we deleted the old one + // for this platform type (if it existed). The stale accountSocials array + // would incorrectly skip this insert if we checked it. + await insertAccountSocial(artistId, social.id); } else { // Create new social record const username = getUsernameFromProfileUrl(value);