fix: add adminGetVideo/adminGetArticle queries to fix 404 on edit pages
Some checks failed
Build and Push Backend Image / build (push) Successful in 43s
Build and Push Frontend Image / build (push) Has been cancelled

The edit page loaders were calling adminListVideos/adminListArticles with the
old pre-pagination signatures and filtering by ID client-side, which broke
after pagination limited results to 50. Now fetches the single item by ID
directly via new adminGetVideo and adminGetArticle backend queries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 11:05:21 +01:00
parent 6f2f3b3529
commit bff354094e
5 changed files with 129 additions and 10 deletions

View File

@@ -96,6 +96,26 @@ builder.queryField("article", (t) =>
}),
);
builder.queryField("adminGetArticle", (t) =>
t.field({
type: ArticleType,
nullable: true,
args: {
id: t.arg.string({ required: true }),
},
resolve: async (_root, args, ctx) => {
requireAdmin(ctx);
const article = await ctx.db
.select()
.from(articles)
.where(eq(articles.id, args.id))
.limit(1);
if (!article[0]) return null;
return enrichArticle(ctx.db, article[0]);
},
}),
);
// ─── Admin queries & mutations ────────────────────────────────────────────────
builder.queryField("adminListArticles", (t) =>

View File

@@ -188,6 +188,22 @@ builder.queryField("video", (t) =>
}),
);
builder.queryField("adminGetVideo", (t) =>
t.field({
type: VideoType,
nullable: true,
args: {
id: t.arg.string({ required: true }),
},
resolve: async (_root, args, ctx) => {
requireAdmin(ctx);
const video = await ctx.db.select().from(videos).where(eq(videos.id, args.id)).limit(1);
if (!video[0]) return null;
return enrichVideo(ctx.db, video[0]);
},
}),
);
builder.queryField("videoLikeStatus", (t) =>
t.field({
type: VideoLikeStatusType,

View File

@@ -1339,6 +1339,51 @@ export async function adminListVideos(
});
}
const ADMIN_GET_VIDEO_QUERY = gql`
query AdminGetVideo($id: String!) {
adminGetVideo(id: $id) {
id
slug
title
description
image
movie
tags
upload_date
premium
featured
likes_count
plays_count
models {
id
artist_name
slug
avatar
}
movie_file {
id
filename
mime_type
duration
}
}
}
`;
export async function adminGetVideo(
id: string,
fetchFn?: typeof globalThis.fetch,
token?: string,
): Promise<Video | null> {
return loggedApiCall("adminGetVideo", async () => {
const client = token ? getAuthClient(token) : getGraphQLClient(fetchFn);
const data = await client.request<{ adminGetVideo: Video | null }>(ADMIN_GET_VIDEO_QUERY, {
id,
});
return data.adminGetVideo;
});
}
const CREATE_VIDEO_MUTATION = gql`
mutation CreateVideo(
$title: String!
@@ -1543,6 +1588,44 @@ export async function adminListArticles(
});
}
const ADMIN_GET_ARTICLE_QUERY = gql`
query AdminGetArticle($id: String!) {
adminGetArticle(id: $id) {
id
slug
title
excerpt
content
image
tags
publish_date
category
featured
author {
id
artist_name
slug
avatar
}
}
}
`;
export async function adminGetArticle(
id: string,
fetchFn?: typeof globalThis.fetch,
token?: string,
): Promise<Article | null> {
return loggedApiCall("adminGetArticle", async () => {
const client = token ? getAuthClient(token) : getGraphQLClient(fetchFn);
const data = await client.request<{ adminGetArticle: Article | null }>(
ADMIN_GET_ARTICLE_QUERY,
{ id },
);
return data.adminGetArticle;
});
}
const CREATE_ARTICLE_MUTATION = gql`
mutation CreateArticle(
$title: String!

View File

@@ -1,16 +1,17 @@
import { adminListArticles, adminListUsers } from "$lib/services";
import { adminGetArticle, adminListUsers } from "$lib/services";
import { error } from "@sveltejs/kit";
export async function load({ params, fetch, cookies }) {
const token = cookies.get("session_token") || "";
const [articles, modelsResult] = await Promise.all([
adminListArticles(fetch, token).catch(() => []),
const [article, modelsResult] = await Promise.all([
adminGetArticle(params.id, fetch, token).catch(() => null),
adminListUsers({ role: "model", limit: 200 }, fetch, token).catch(() => ({
items: [],
total: 0,
})),
]);
const article = articles.find((a) => a.id === params.id);
if (!article) throw error(404, "Article not found");
return { article, authors: modelsResult.items };
}

View File

@@ -1,15 +1,14 @@
import { adminListVideos, getModels } from "$lib/services";
import { adminGetVideo, getModels } from "$lib/services";
import { error } from "@sveltejs/kit";
export async function load({ params, fetch, cookies }) {
const token = cookies.get("session_token") || "";
const [allVideos, models] = await Promise.all([
adminListVideos(fetch, token).catch(() => []),
getModels(fetch).catch(() => []),
const [video, modelsResult] = await Promise.all([
adminGetVideo(params.id, fetch, token).catch(() => null),
getModels({}, fetch).catch(() => ({ items: [], total: 0 })),
]);
const video = allVideos.find((v) => v.id === params.id);
if (!video) throw error(404, "Video not found");
return { video, models };
return { video, models: modelsResult.items };
}