mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-10-16 06:25:42 -04:00
fix(server): store raw TMDB paths in browse upserts to prevent double-resolution
The explore, discover, and search procedures were calling tmdbImageUrl() on raw TMDB paths before passing them to ensureBrowseTitlesExist() and ensureBrowsePersonsExist(). This stored already-resolved paths like /images/posters/abc.jpg in the DB. When getOrFetchTitle() later read these rows and called tmdbImageUrl() again, the result was a doubled path (/images/posters/images/posters/abc.jpg) that returned 404. Fix: pass raw TMDB paths for DB storage, resolve via tmdbImageUrl() only when building the client response. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
3 files changed
+23
-10
No files matched your search
@@ -41,7 +41,7 @@ export const discover = os.discover.use(authed).handler(async ({ input, context
|
|||||||
tmdbId: r.id,
|
tmdbId: r.id,
|
||||||
type: input.type,
|
type: input.type,
|
||||||
title: r.title ?? r.name ?? "",
|
title: r.title ?? r.name ?? "",
|
||||||
posterPath: tmdbImageUrl(r.poster_path ?? null, "posters"),
|
posterPath: r.poster_path ?? null,
|
||||||
releaseDate: (r.release_date as string | undefined) ?? null,
|
releaseDate: (r.release_date as string | undefined) ?? null,
|
||||||
firstAirDate: (r.first_air_date as string | undefined) ?? null,
|
firstAirDate: (r.first_air_date as string | undefined) ?? null,
|
||||||
voteAverage: r.vote_average ?? null,
|
voteAverage: r.vote_average ?? null,
|
||||||
@@ -52,6 +52,7 @@ export const discover = os.discover.use(authed).handler(async ({ input, context
|
|||||||
const entry = titleMap.get(`${item.tmdbId}-${item.type}`);
|
const entry = titleMap.get(`${item.tmdbId}-${item.type}`);
|
||||||
return Object.assign(item, {
|
return Object.assign(item, {
|
||||||
id: entry?.id ?? "",
|
id: entry?.id ?? "",
|
||||||
|
posterPath: tmdbImageUrl(item.posterPath, "posters"),
|
||||||
posterThumbHash: entry?.posterThumbHash ?? null,
|
posterThumbHash: entry?.posterThumbHash ?? null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export const trending = os.explore.trending.use(authed).handler(async ({ input,
|
|||||||
tmdbId: r.id as number,
|
tmdbId: r.id as number,
|
||||||
type: mediaType as "movie" | "tv",
|
type: mediaType as "movie" | "tv",
|
||||||
title: ((r.title ?? r.name) as string) || "",
|
title: ((r.title ?? r.name) as string) || "",
|
||||||
posterPath: tmdbImageUrl((r.poster_path as string) ?? null, "posters"),
|
posterPath: (r.poster_path as string) ?? null,
|
||||||
releaseDate: (r.release_date as string | undefined) ?? null,
|
releaseDate: (r.release_date as string | undefined) ?? null,
|
||||||
firstAirDate: (r.first_air_date as string | undefined) ?? null,
|
firstAirDate: (r.first_air_date as string | undefined) ?? null,
|
||||||
voteAverage: (r.vote_average as number | undefined) ?? null,
|
voteAverage: (r.vote_average as number | undefined) ?? null,
|
||||||
@@ -52,7 +52,7 @@ export const trending = os.explore.trending.use(authed).handler(async ({ input,
|
|||||||
tmdbId: heroResult.id as number,
|
tmdbId: heroResult.id as number,
|
||||||
type: heroResult.media_type as "movie" | "tv",
|
type: heroResult.media_type as "movie" | "tv",
|
||||||
title: ((heroResult.title ?? heroResult.name) as string | undefined) ?? "",
|
title: ((heroResult.title ?? heroResult.name) as string | undefined) ?? "",
|
||||||
posterPath: tmdbImageUrl((heroResult.poster_path as string) ?? null, "posters"),
|
posterPath: (heroResult.poster_path as string) ?? null,
|
||||||
releaseDate: (heroResult.release_date as string | undefined) ?? null,
|
releaseDate: (heroResult.release_date as string | undefined) ?? null,
|
||||||
firstAirDate: (heroResult.first_air_date as string | undefined) ?? null,
|
firstAirDate: (heroResult.first_air_date as string | undefined) ?? null,
|
||||||
voteAverage: (heroResult.vote_average as number | undefined) ?? null,
|
voteAverage: (heroResult.vote_average as number | undefined) ?? null,
|
||||||
@@ -66,6 +66,7 @@ export const trending = os.explore.trending.use(authed).handler(async ({ input,
|
|||||||
const entry = titleMap.get(`${item.tmdbId}-${item.type}`);
|
const entry = titleMap.get(`${item.tmdbId}-${item.type}`);
|
||||||
return Object.assign(item, {
|
return Object.assign(item, {
|
||||||
id: entry?.id ?? "",
|
id: entry?.id ?? "",
|
||||||
|
posterPath: tmdbImageUrl(item.posterPath, "posters"),
|
||||||
posterThumbHash: entry?.posterThumbHash ?? null,
|
posterThumbHash: entry?.posterThumbHash ?? null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -115,7 +116,7 @@ export const popular = os.explore.popular.use(authed).handler(async ({ input, co
|
|||||||
tmdbId: r.id as number,
|
tmdbId: r.id as number,
|
||||||
type: input.type,
|
type: input.type,
|
||||||
title: ((r.title ?? r.name) as string) || "",
|
title: ((r.title ?? r.name) as string) || "",
|
||||||
posterPath: tmdbImageUrl((r.poster_path as string) ?? null, "posters"),
|
posterPath: (r.poster_path as string) ?? null,
|
||||||
releaseDate: (r.release_date as string | undefined) ?? null,
|
releaseDate: (r.release_date as string | undefined) ?? null,
|
||||||
firstAirDate: (r.first_air_date as string | undefined) ?? null,
|
firstAirDate: (r.first_air_date as string | undefined) ?? null,
|
||||||
voteAverage: (r.vote_average as number | undefined) ?? null,
|
voteAverage: (r.vote_average as number | undefined) ?? null,
|
||||||
@@ -126,6 +127,7 @@ export const popular = os.explore.popular.use(authed).handler(async ({ input, co
|
|||||||
const entry = titleMap.get(`${item.tmdbId}-${item.type}`);
|
const entry = titleMap.get(`${item.tmdbId}-${item.type}`);
|
||||||
return Object.assign(item, {
|
return Object.assign(item, {
|
||||||
id: entry?.id ?? "",
|
id: entry?.id ?? "",
|
||||||
|
posterPath: tmdbImageUrl(item.posterPath, "posters"),
|
||||||
posterThumbHash: entry?.posterThumbHash ?? null,
|
posterThumbHash: entry?.posterThumbHash ?? null,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const search = os.search.use(authed).handler(async ({ input }) => {
|
|||||||
type: "person" as const,
|
type: "person" as const,
|
||||||
title: r.name ?? "",
|
title: r.name ?? "",
|
||||||
posterPath: null,
|
posterPath: null,
|
||||||
profilePath: tmdbImageUrl(r.profile_path ?? null, "profiles"),
|
profilePath: r.profile_path ?? null,
|
||||||
overview: null,
|
overview: null,
|
||||||
releaseDate: null,
|
releaseDate: null,
|
||||||
popularity: r.popularity ?? null,
|
popularity: r.popularity ?? null,
|
||||||
@@ -53,7 +53,12 @@ export const search = os.search.use(authed).handler(async ({ input }) => {
|
|||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
results: personItems.map((r) => Object.assign(r, { id: personMap.get(r.tmdbId) })),
|
results: personItems.map((r) =>
|
||||||
|
Object.assign(r, {
|
||||||
|
id: personMap.get(r.tmdbId),
|
||||||
|
profilePath: tmdbImageUrl(r.profilePath, "profiles"),
|
||||||
|
}),
|
||||||
|
),
|
||||||
page: personResults.page ?? input.page,
|
page: personResults.page ?? input.page,
|
||||||
totalPages: personResults.total_pages ?? 1,
|
totalPages: personResults.total_pages ?? 1,
|
||||||
totalResults: personResults.total_results ?? 0,
|
totalResults: personResults.total_results ?? 0,
|
||||||
@@ -89,7 +94,7 @@ export const search = os.search.use(authed).handler(async ({ input }) => {
|
|||||||
type: "person" as const,
|
type: "person" as const,
|
||||||
title: r.name ?? "Unknown",
|
title: r.name ?? "Unknown",
|
||||||
posterPath: null,
|
posterPath: null,
|
||||||
profilePath: tmdbImageUrl(r.profile_path ?? null, "profiles"),
|
profilePath: r.profile_path ?? null,
|
||||||
overview: null,
|
overview: null,
|
||||||
releaseDate: null,
|
releaseDate: null,
|
||||||
popularity: r.popularity ?? null,
|
popularity: r.popularity ?? null,
|
||||||
@@ -108,7 +113,7 @@ export const search = os.search.use(authed).handler(async ({ input }) => {
|
|||||||
title: r.title ?? r.name ?? "",
|
title: r.title ?? r.name ?? "",
|
||||||
overview: r.overview ?? null,
|
overview: r.overview ?? null,
|
||||||
releaseDate: r.release_date ?? r.first_air_date ?? null,
|
releaseDate: r.release_date ?? r.first_air_date ?? null,
|
||||||
posterPath: tmdbImageUrl(r.poster_path ?? null, "posters"),
|
posterPath: r.poster_path ?? null,
|
||||||
profilePath: null,
|
profilePath: null,
|
||||||
popularity: r.popularity ?? null,
|
popularity: r.popularity ?? null,
|
||||||
voteAverage: r.vote_average ?? null,
|
voteAverage: r.vote_average ?? null,
|
||||||
@@ -137,9 +142,14 @@ export const search = os.search.use(authed).handler(async ({ input }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const results = mapped.map((r) => {
|
const results = mapped.map((r) => {
|
||||||
if (r.type === "person") return Object.assign(r, { id: personMap.get(r.tmdbId) });
|
if (r.type === "person") {
|
||||||
|
return Object.assign(r, {
|
||||||
|
id: personMap.get(r.tmdbId),
|
||||||
|
profilePath: tmdbImageUrl(r.profilePath, "profiles"),
|
||||||
|
});
|
||||||
|
}
|
||||||
const entry = titleMap.get(`${r.tmdbId}-${r.type}`);
|
const entry = titleMap.get(`${r.tmdbId}-${r.type}`);
|
||||||
return Object.assign(r, { id: entry?.id });
|
return Object.assign(r, { id: entry?.id, posterPath: tmdbImageUrl(r.posterPath, "posters") });
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in new issue
Block a user