Skip to content

Commit d4f6a84

Browse files
sweetmantechclaude
andauthored
fix: add system prompt to save Spotify URL to artist socials (#143)
* fix: add system prompt to save Spotify URL to artist socials The update_artist_socials step now has a system prompt instructing the AI to save the Spotify profile URL from the search results. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * debug: add logging to updateArtistSocials to trace empty response * fix: normalize profile URLs to match database format The database stores profile URLs without the protocol (e.g., "open.spotify.com/artist/123" instead of "https://..."). The selectSocials query was using the full URL with protocol, causing it to miss existing records. When insertSocials was then called, it failed with a duplicate key violation. - Add normalizeProfileUrl function to strip protocol and trailing slash - Use normalized URLs in updateArtistSocials for both query and insert - Add comprehensive tests for normalizeProfileUrl Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: remove debug logging from updateArtistSocials --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent dd0deda commit d4f6a84

File tree

4 files changed

+65
-5
lines changed

4 files changed

+65
-5
lines changed

lib/artist/updateArtistSocials.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getSocialPlatformByLink } from "@/lib/artists/getSocialPlatformByLink";
22
import { getUsernameFromProfileUrl } from "@/lib/socials/getUsernameFromProfileUrl";
3+
import { normalizeProfileUrl } from "@/lib/socials/normalizeProfileUrl";
34
import { selectAccountSocials } from "@/lib/supabase/account_socials/selectAccountSocials";
45
import { deleteAccountSocial } from "@/lib/supabase/account_socials/deleteAccountSocial";
56
import { insertAccountSocial } from "@/lib/supabase/account_socials/insertAccountSocial";
@@ -23,8 +24,13 @@ export async function updateArtistSocials(
2324

2425
// Process each platform type
2526
const profilePromises = Object.entries(profileUrls).map(async ([type, value]) => {
26-
const socials = value ? await selectSocials({ profile_url: value }) : null;
27+
const normalizedUrl = normalizeProfileUrl(value);
28+
29+
const socials = normalizedUrl
30+
? await selectSocials({ profile_url: normalizedUrl })
31+
: null;
2732
const social = socials && socials.length > 0 ? socials[0] : null;
33+
2834
const existingSocial = (accountSocials || []).find(
2935
(account_social: AccountSocialWithSocial) =>
3036
getSocialPlatformByLink(account_social.social?.profile_url || "") === type,
@@ -36,7 +42,7 @@ export async function updateArtistSocials(
3642
}
3743

3844
// Insert new social if URL provided
39-
if (value) {
45+
if (normalizedUrl) {
4046
if (social) {
4147
// Social already exists, check if account_social relationship exists
4248
const existing = (accountSocials || []).find(
@@ -47,10 +53,11 @@ export async function updateArtistSocials(
4753
}
4854
} else {
4955
// Create new social record
56+
const username = getUsernameFromProfileUrl(value);
5057
const newSocials = await insertSocials([
5158
{
52-
username: getUsernameFromProfileUrl(value),
53-
profile_url: value,
59+
username,
60+
profile_url: normalizedUrl,
5461
},
5562
]);
5663
if (newSocials.length > 0) {

lib/chat/toolChains/createNewArtistToolChain.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ export const createNewArtistToolChain: ToolChainItem[] = [
88
system:
99
"From the get_spotify_search results, select the artist whose name best matches the user-provided artist name (prefer exact, case-insensitive match; otherwise choose the closest by name and popularity). Update the account using the update_account_info tool with the artist's basic information: name, image, label, etc.",
1010
},
11-
{ toolName: "update_artist_socials" },
11+
{
12+
toolName: "update_artist_socials",
13+
system:
14+
"Using the matched Spotify artist from the get_spotify_search results, update the artist's socials with the Spotify profile URL (found in external_urls.spotify). Pass the URL in the urls array to update_artist_socials.",
15+
},
1216
{ toolName: "artist_deep_research" },
1317
{ toolName: "spotify_deep_research" },
1418
{ toolName: "get_artist_socials" },
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { describe, it, expect } from "vitest";
2+
import { normalizeProfileUrl } from "../normalizeProfileUrl";
3+
4+
describe("normalizeProfileUrl", () => {
5+
it("removes https:// protocol from URL", () => {
6+
expect(normalizeProfileUrl("https://open.spotify.com/artist/123")).toBe(
7+
"open.spotify.com/artist/123",
8+
);
9+
});
10+
11+
it("removes http:// protocol from URL", () => {
12+
expect(normalizeProfileUrl("http://twitter.com/user")).toBe("twitter.com/user");
13+
});
14+
15+
it("returns URL unchanged if no protocol", () => {
16+
expect(normalizeProfileUrl("open.spotify.com/artist/123")).toBe(
17+
"open.spotify.com/artist/123",
18+
);
19+
});
20+
21+
it("handles empty string", () => {
22+
expect(normalizeProfileUrl("")).toBe("");
23+
});
24+
25+
it("handles null/undefined", () => {
26+
expect(normalizeProfileUrl(null as unknown as string)).toBe("");
27+
expect(normalizeProfileUrl(undefined as unknown as string)).toBe("");
28+
});
29+
30+
it("removes trailing slash", () => {
31+
expect(normalizeProfileUrl("https://instagram.com/user/")).toBe(
32+
"instagram.com/user",
33+
);
34+
});
35+
});

lib/socials/normalizeProfileUrl.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Normalizes a profile URL by removing the protocol and trailing slash.
3+
* This ensures consistent URL format for database queries and storage.
4+
*
5+
* @param url - The profile URL to normalize
6+
* @returns The normalized URL without protocol or trailing slash
7+
*/
8+
export function normalizeProfileUrl(url: string | null | undefined): string {
9+
if (!url) return "";
10+
11+
return url
12+
.replace(/^https?:\/\//, "")
13+
.replace(/\/$/, "");
14+
}

0 commit comments

Comments
 (0)