34 lines
1.2 KiB
TypeScript
34 lines
1.2 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { revalidatePath } from "next/cache";
|
|
import { rescanVideoIndex } from "@/lib/video";
|
|
import { rawDb } from "@/lib/db/client";
|
|
import { assertLocalRequest } from "@/lib/api/localOnly";
|
|
|
|
export const runtime = "nodejs";
|
|
export const dynamic = "force-dynamic";
|
|
|
|
export async function POST(req: NextRequest) {
|
|
const blocked = assertLocalRequest(req);
|
|
if (blocked) return blocked;
|
|
|
|
const t0 = Date.now();
|
|
const force = req.nextUrl.searchParams.get("force") === "1";
|
|
const idx = await rescanVideoIndex({ force });
|
|
// Bust the RSC cache for detail pages so file-size / duration
|
|
// refresh without a navigation. Skip the layout invalidation —
|
|
// it triggers a full-app re-render and isn't needed for the
|
|
// metadata badges we actually changed.
|
|
revalidatePath("/id/[code]", "page");
|
|
// codes count comes from the DB now, not an in-memory Map. Cheap.
|
|
const distinctCodesRow = rawDb
|
|
.prepare(`SELECT COUNT(DISTINCT upper(code)) AS n FROM video_metadata`)
|
|
.get() as { n: number };
|
|
return NextResponse.json({
|
|
ok: true,
|
|
count: idx.count,
|
|
codes: distinctCodesRow.n,
|
|
rootsScanned: idx.rootsScanned,
|
|
elapsedMs: Date.now() - t0,
|
|
});
|
|
}
|