From e8dd9dfdc0538e68515e5dc99a26718eb53befcd Mon Sep 17 00:00:00 2001 From: Arpit Gupta Date: Thu, 9 Apr 2026 04:11:48 +0530 Subject: [PATCH 1/4] refactor: move artist detail reads to api --- app/api/artist/route.tsx | 33 --------------------------------- hooks/useArtistInstruction.ts | 14 +++++++++----- hooks/useArtistKnowledge.ts | 15 +++++++++------ lib/getArtist.tsx | 27 ++++++++++++++++++++++----- 4 files changed, 40 insertions(+), 49 deletions(-) delete mode 100644 app/api/artist/route.tsx diff --git a/app/api/artist/route.tsx b/app/api/artist/route.tsx deleted file mode 100644 index 6c5072742..000000000 --- a/app/api/artist/route.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import supabase from "@/lib/supabase/serverClient"; -import { NextRequest } from "next/server"; - -export async function GET(req: NextRequest) { - const artistId = req.nextUrl.searchParams.get("artistId"); - - try { - const { data: account } = await supabase - .from("accounts") - .select("*, account_info(*), account_socials(*)") - .eq("id", artistId) - .single(); - if (!account) throw new Error("failed"); - - return Response.json( - { - artist: { - ...account.account_info[0], - ...account, - }, - }, - { status: 200 }, - ); - } catch (error) { - console.error(error); - const message = error instanceof Error ? error.message : "failed"; - return Response.json({ message }, { status: 400 }); - } -} - -export const dynamic = "force-dynamic"; -export const fetchCache = "force-no-store"; -export const revalidate = 0; diff --git a/hooks/useArtistInstruction.ts b/hooks/useArtistInstruction.ts index 2e010642d..3cf2e9b84 100644 --- a/hooks/useArtistInstruction.ts +++ b/hooks/useArtistInstruction.ts @@ -1,15 +1,20 @@ import { useQuery } from "@tanstack/react-query"; +import { usePrivy } from "@privy-io/react-auth"; +import getArtist from "@/lib/getArtist"; export function useArtistInstruction(artistId?: string) { + const { getAccessToken } = usePrivy(); + return useQuery({ queryKey: ["artist-instruction", artistId], enabled: Boolean(artistId), queryFn: async () => { if (!artistId) return undefined; - const res = await fetch(`/api/artist?artistId=${encodeURIComponent(artistId)}`); - if (!res.ok) return undefined; - const json = await res.json(); - return json?.artist?.instruction || undefined; + const accessToken = await getAccessToken(); + if (!accessToken) return undefined; + + const artist = await getArtist(artistId, accessToken); + return artist?.instruction || undefined; }, staleTime: 5 * 60 * 1000, }); @@ -17,4 +22,3 @@ export function useArtistInstruction(artistId?: string) { export default useArtistInstruction; - diff --git a/hooks/useArtistKnowledge.ts b/hooks/useArtistKnowledge.ts index 262ab49ef..16d2e631d 100644 --- a/hooks/useArtistKnowledge.ts +++ b/hooks/useArtistKnowledge.ts @@ -1,17 +1,21 @@ import { useQuery } from "@tanstack/react-query"; +import { usePrivy } from "@privy-io/react-auth"; +import getArtist from "@/lib/getArtist"; import type { KnowledgeBaseEntry } from "@/lib/supabase/getArtistKnowledge"; export function useArtistKnowledge(artistId?: string) { + const { getAccessToken } = usePrivy(); + return useQuery({ queryKey: ["artist-knowledge", artistId], enabled: Boolean(artistId), queryFn: async () => { if (!artistId) return []; - const res = await fetch(`/api/artist?artistId=${encodeURIComponent(artistId)}`); - if (!res.ok) return []; - const json = await res.json(); - const knowledges: KnowledgeBaseEntry[] = - json?.artist?.account_info?.[0]?.knowledges || json?.artist?.knowledges || []; + const accessToken = await getAccessToken(); + if (!accessToken) return []; + + const artist = await getArtist(artistId, accessToken); + const knowledges: KnowledgeBaseEntry[] = artist?.knowledges || []; return Array.isArray(knowledges) ? knowledges : []; }, staleTime: 5 * 60 * 1000, @@ -20,4 +24,3 @@ export function useArtistKnowledge(artistId?: string) { export default useArtistKnowledge; - diff --git a/lib/getArtist.tsx b/lib/getArtist.tsx index eb984a9ed..8a9c45287 100644 --- a/lib/getArtist.tsx +++ b/lib/getArtist.tsx @@ -1,12 +1,29 @@ -const getArtist = async (artistId: string) => { +import { getClientApiBaseUrl } from "@/lib/api/getClientApiBaseUrl"; +import type { ArtistRecord } from "@/types/Artist"; + +const getArtist = async ( + artistId: string, + accessToken: string, +): Promise => { try { - const response = await fetch(`/api/artist?artistId=${artistId}`); + const response = await fetch( + `${getClientApiBaseUrl()}/api/artists/${encodeURIComponent(artistId)}`, + { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }, + ); + + if (!response.ok) { + return null; + } const data = await response.json(); - return data?.artist; - } catch (error) { - return { error }; + return data?.artist ?? null; + } catch { + return null; } }; From 00ce709e8a71a44f213f52df5ad6cec7bbe363c9 Mon Sep 17 00:00:00 2001 From: Arpit Gupta Date: Thu, 9 Apr 2026 04:40:54 +0530 Subject: [PATCH 2/4] fix: harden artist detail queries --- hooks/useArtistInstruction.ts | 13 ++++----- hooks/useArtistKnowledge.ts | 13 ++++----- lib/artists/fetchAuthenticatedArtist.ts | 16 +++++++++++ lib/getArtist.tsx | 35 +++++++++++++------------ 4 files changed, 44 insertions(+), 33 deletions(-) create mode 100644 lib/artists/fetchAuthenticatedArtist.ts diff --git a/hooks/useArtistInstruction.ts b/hooks/useArtistInstruction.ts index 3cf2e9b84..77757224d 100644 --- a/hooks/useArtistInstruction.ts +++ b/hooks/useArtistInstruction.ts @@ -1,19 +1,17 @@ import { useQuery } from "@tanstack/react-query"; import { usePrivy } from "@privy-io/react-auth"; -import getArtist from "@/lib/getArtist"; +import { fetchAuthenticatedArtist } from "@/lib/artists/fetchAuthenticatedArtist"; export function useArtistInstruction(artistId?: string) { - const { getAccessToken } = usePrivy(); + const { getAccessToken, authenticated } = usePrivy(); return useQuery({ - queryKey: ["artist-instruction", artistId], - enabled: Boolean(artistId), + queryKey: ["artist-instruction", artistId, authenticated], + enabled: Boolean(artistId) && authenticated, queryFn: async () => { if (!artistId) return undefined; - const accessToken = await getAccessToken(); - if (!accessToken) return undefined; - const artist = await getArtist(artistId, accessToken); + const artist = await fetchAuthenticatedArtist(artistId, getAccessToken); return artist?.instruction || undefined; }, staleTime: 5 * 60 * 1000, @@ -21,4 +19,3 @@ export function useArtistInstruction(artistId?: string) { } export default useArtistInstruction; - diff --git a/hooks/useArtistKnowledge.ts b/hooks/useArtistKnowledge.ts index 16d2e631d..ac2a2c14c 100644 --- a/hooks/useArtistKnowledge.ts +++ b/hooks/useArtistKnowledge.ts @@ -1,20 +1,18 @@ import { useQuery } from "@tanstack/react-query"; import { usePrivy } from "@privy-io/react-auth"; -import getArtist from "@/lib/getArtist"; +import { fetchAuthenticatedArtist } from "@/lib/artists/fetchAuthenticatedArtist"; import type { KnowledgeBaseEntry } from "@/lib/supabase/getArtistKnowledge"; export function useArtistKnowledge(artistId?: string) { - const { getAccessToken } = usePrivy(); + const { getAccessToken, authenticated } = usePrivy(); return useQuery({ - queryKey: ["artist-knowledge", artistId], - enabled: Boolean(artistId), + queryKey: ["artist-knowledge", artistId, authenticated], + enabled: Boolean(artistId) && authenticated, queryFn: async () => { if (!artistId) return []; - const accessToken = await getAccessToken(); - if (!accessToken) return []; - const artist = await getArtist(artistId, accessToken); + const artist = await fetchAuthenticatedArtist(artistId, getAccessToken); const knowledges: KnowledgeBaseEntry[] = artist?.knowledges || []; return Array.isArray(knowledges) ? knowledges : []; }, @@ -23,4 +21,3 @@ export function useArtistKnowledge(artistId?: string) { } export default useArtistKnowledge; - diff --git a/lib/artists/fetchAuthenticatedArtist.ts b/lib/artists/fetchAuthenticatedArtist.ts new file mode 100644 index 000000000..aac93ac2f --- /dev/null +++ b/lib/artists/fetchAuthenticatedArtist.ts @@ -0,0 +1,16 @@ +import type { PrivyClient } from "@privy-io/react-auth"; +import getArtist from "@/lib/getArtist"; + +type GetAccessToken = PrivyClient["getAccessToken"]; + +export async function fetchAuthenticatedArtist( + artistId: string, + getAccessToken: GetAccessToken, +) { + const accessToken = await getAccessToken(); + if (!accessToken) { + throw new Error("Please sign in to view artist details"); + } + + return getArtist(artistId, accessToken); +} diff --git a/lib/getArtist.tsx b/lib/getArtist.tsx index 8a9c45287..29e05f027 100644 --- a/lib/getArtist.tsx +++ b/lib/getArtist.tsx @@ -4,27 +4,28 @@ import type { ArtistRecord } from "@/types/Artist"; const getArtist = async ( artistId: string, accessToken: string, -): Promise => { - try { - const response = await fetch( - `${getClientApiBaseUrl()}/api/artists/${encodeURIComponent(artistId)}`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - }, +) : Promise => { + const response = await fetch( + `${getClientApiBaseUrl()}/api/artists/${encodeURIComponent(artistId)}`, + { + headers: { + Authorization: `Bearer ${accessToken}`, }, - ); + }, + ); - if (!response.ok) { - return null; - } + if (!response.ok) { + const responseText = await response.text(); + throw new Error( + responseText + ? `Failed to fetch artist: ${response.status} ${responseText}` + : `Failed to fetch artist: ${response.status}`, + ); + } - const data = await response.json(); + const data = await response.json(); - return data?.artist ?? null; - } catch { - return null; - } + return data?.artist ?? null; }; export default getArtist; From 8ba1efffe0a81bf9747d9358d840c96c60a9344e Mon Sep 17 00:00:00 2001 From: Arpit Gupta Date: Thu, 9 Apr 2026 04:44:40 +0530 Subject: [PATCH 3/4] refactor: inline artist token reads --- hooks/useArtistInstruction.ts | 8 ++++++-- hooks/useArtistKnowledge.ts | 8 ++++++-- lib/artists/fetchAuthenticatedArtist.ts | 16 ---------------- 3 files changed, 12 insertions(+), 20 deletions(-) delete mode 100644 lib/artists/fetchAuthenticatedArtist.ts diff --git a/hooks/useArtistInstruction.ts b/hooks/useArtistInstruction.ts index 77757224d..f6b4b34f5 100644 --- a/hooks/useArtistInstruction.ts +++ b/hooks/useArtistInstruction.ts @@ -1,6 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import { usePrivy } from "@privy-io/react-auth"; -import { fetchAuthenticatedArtist } from "@/lib/artists/fetchAuthenticatedArtist"; +import getArtist from "@/lib/getArtist"; export function useArtistInstruction(artistId?: string) { const { getAccessToken, authenticated } = usePrivy(); @@ -10,8 +10,12 @@ export function useArtistInstruction(artistId?: string) { enabled: Boolean(artistId) && authenticated, queryFn: async () => { if (!artistId) return undefined; + const accessToken = await getAccessToken(); + if (!accessToken) { + throw new Error("Please sign in to view artist details"); + } - const artist = await fetchAuthenticatedArtist(artistId, getAccessToken); + const artist = await getArtist(artistId, accessToken); return artist?.instruction || undefined; }, staleTime: 5 * 60 * 1000, diff --git a/hooks/useArtistKnowledge.ts b/hooks/useArtistKnowledge.ts index ac2a2c14c..2a84826c5 100644 --- a/hooks/useArtistKnowledge.ts +++ b/hooks/useArtistKnowledge.ts @@ -1,6 +1,6 @@ import { useQuery } from "@tanstack/react-query"; import { usePrivy } from "@privy-io/react-auth"; -import { fetchAuthenticatedArtist } from "@/lib/artists/fetchAuthenticatedArtist"; +import getArtist from "@/lib/getArtist"; import type { KnowledgeBaseEntry } from "@/lib/supabase/getArtistKnowledge"; export function useArtistKnowledge(artistId?: string) { @@ -11,8 +11,12 @@ export function useArtistKnowledge(artistId?: string) { enabled: Boolean(artistId) && authenticated, queryFn: async () => { if (!artistId) return []; + const accessToken = await getAccessToken(); + if (!accessToken) { + throw new Error("Please sign in to view artist details"); + } - const artist = await fetchAuthenticatedArtist(artistId, getAccessToken); + const artist = await getArtist(artistId, accessToken); const knowledges: KnowledgeBaseEntry[] = artist?.knowledges || []; return Array.isArray(knowledges) ? knowledges : []; }, diff --git a/lib/artists/fetchAuthenticatedArtist.ts b/lib/artists/fetchAuthenticatedArtist.ts deleted file mode 100644 index aac93ac2f..000000000 --- a/lib/artists/fetchAuthenticatedArtist.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { PrivyClient } from "@privy-io/react-auth"; -import getArtist from "@/lib/getArtist"; - -type GetAccessToken = PrivyClient["getAccessToken"]; - -export async function fetchAuthenticatedArtist( - artistId: string, - getAccessToken: GetAccessToken, -) { - const accessToken = await getAccessToken(); - if (!accessToken) { - throw new Error("Please sign in to view artist details"); - } - - return getArtist(artistId, accessToken); -} From 1eb00d98b6f59dbe31a9ed0cd13d970f2da34b5b Mon Sep 17 00:00:00 2001 From: Arpit Gupta Date: Thu, 9 Apr 2026 04:46:14 +0530 Subject: [PATCH 4/4] fix: simplify artist query keys --- hooks/useArtistInstruction.ts | 2 +- hooks/useArtistKnowledge.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hooks/useArtistInstruction.ts b/hooks/useArtistInstruction.ts index f6b4b34f5..3441bc3a7 100644 --- a/hooks/useArtistInstruction.ts +++ b/hooks/useArtistInstruction.ts @@ -6,7 +6,7 @@ export function useArtistInstruction(artistId?: string) { const { getAccessToken, authenticated } = usePrivy(); return useQuery({ - queryKey: ["artist-instruction", artistId, authenticated], + queryKey: ["artist-instruction", artistId], enabled: Boolean(artistId) && authenticated, queryFn: async () => { if (!artistId) return undefined; diff --git a/hooks/useArtistKnowledge.ts b/hooks/useArtistKnowledge.ts index 2a84826c5..dab95bbe6 100644 --- a/hooks/useArtistKnowledge.ts +++ b/hooks/useArtistKnowledge.ts @@ -7,7 +7,7 @@ export function useArtistKnowledge(artistId?: string) { const { getAccessToken, authenticated } = usePrivy(); return useQuery({ - queryKey: ["artist-knowledge", artistId, authenticated], + queryKey: ["artist-knowledge", artistId], enabled: Boolean(artistId) && authenticated, queryFn: async () => { if (!artistId) return [];