spb/note-spboucher-ai
Public
1import { z } from "zod";2import { handler, parseBody, uuid } from "@/lib/api";3import { backlinkStats, unlinkedMentions, linkMention, dismissMention } from "@/lib/graph/backlinks";4import { audit } from "@/lib/audit";56/** GET ?q=&pageId= → { pages, mentions } */7export const GET = handler(async ({ req, ws }) => {8 const u = new URL(req.url).searchParams; const pid = uuid.safeParse(u.get("pageId"));9 const [pages, mentions] = await Promise.all([backlinkStats(ws.id, { q: u.get("q") ?? "" }), unlinkedMentions(ws.id, { pageId: pid.success ? pid.data : null })]);10 return Response.json({ pages, mentions }, { headers: { "cache-control": "private, no-store" } });11});1213/** POST { action: "link" | "dismiss" | "undismiss", fromId, toId } */14export const POST = handler(async ({ req, ws, user }) => {15 const b = await parseBody(req, z.object({ action: z.enum(["link", "dismiss", "undismiss"]), fromId: uuid, toId: uuid }));16 if (b.action === "link") { await linkMention(ws.id, b.fromId, b.toId); await audit(user.id, "backlinks.link", { type: "page", id: b.fromId }, { to: b.toId }); return Response.json({ ok: true }); }17 await dismissMention(b.fromId, b.toId, b.action === "undismiss");18 return Response.json({ ok: true });19});20