Images now load direct from images.04080616.xyz. Removes read-side signing (signUrl/signCoverUrls + callers), unlocking browser and edge caching since URLs are stable. Presigned upload kept for /api/upload. PageReader retries failed loads via onError as a safety net. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
31 lines
912 B
TypeScript
31 lines
912 B
TypeScript
import { prisma } from "@/lib/db";
|
|
import { decodeId } from "@/lib/hashids";
|
|
import { withGuards } from "@/lib/api-guards";
|
|
|
|
export const GET = withGuards(
|
|
{ rateLimit: { key: "pages", limit: 300, windowMs: 60_000 } },
|
|
async (request) => {
|
|
const { searchParams } = new URL(request.url);
|
|
const chapterId = decodeId(searchParams.get("chapter") ?? "");
|
|
const offset = Math.max(parseInt(searchParams.get("offset") ?? "0", 10), 0);
|
|
const limit = Math.min(
|
|
Math.max(parseInt(searchParams.get("limit") ?? "7", 10), 1),
|
|
20
|
|
);
|
|
|
|
if (chapterId === null) {
|
|
return Response.json({ error: "Missing chapter" }, { status: 400 });
|
|
}
|
|
|
|
const pages = await prisma.page.findMany({
|
|
where: { chapterId },
|
|
orderBy: { number: "asc" },
|
|
skip: offset,
|
|
take: limit,
|
|
select: { number: true, imageUrl: true },
|
|
});
|
|
|
|
return Response.json(pages);
|
|
}
|
|
);
|