feat: scaffold headless frontend integration per design doc

This commit is contained in:
2026-08-06 15:51:59 +08:00
parent b0919bf8b5
commit 7e30631c68
28 changed files with 708 additions and 126 deletions
+34
View File
@@ -0,0 +1,34 @@
import { revalidateTag } from "next/cache";
import { NextRequest, NextResponse } from "next/server";
/**
* 接收 Wagtail `page_published` signal 发出的发布通知,
* 对 fetch 缓存标签做精准失效(详见 documents/设计方案分析与完善版.md §2.7)。
*
* 后端调用示例(apps/core/signals.py):
* POST {FRONTEND_REVALIDATE_URL}
* Headers: Authorization: Bearer {REVALIDATE_SECRET}
* Body: { "tags": ["page:1", "/some/url/"] }
*/
export async function POST(request: NextRequest) {
const authHeader = request.headers.get("authorization");
const expected = `Bearer ${process.env.REVALIDATE_SECRET}`;
if (!process.env.REVALIDATE_SECRET || authHeader !== expected) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const body = await request.json().catch(() => null);
const tags: string[] = body?.tags ?? [];
if (!Array.isArray(tags) || tags.length === 0) {
return NextResponse.json({ error: "No tags provided" }, { status: 400 });
}
for (const tag of tags) {
// Next.js 16 要求传入 cache profile"max" 表示立即使该标签下的缓存完全失效。
revalidateTag(tag, "max");
}
return NextResponse.json({ revalidated: tags });
}