import { z } from "zod"; import { auth } from "@/app/(auth)/auth"; import type { ArtifactKind } from "@/components/chat/artifact"; import { deleteDocumentsByIdAfterTimestamp, getDocumentsById, saveDocument, updateDocumentContent, } from "@/lib/db/queries"; import { ChatbotError } from "@/lib/errors"; const documentSchema = z.object({ content: z.string(), title: z.string(), kind: z.enum(["text", "code", "image", "sheet"]), isManualEdit: z.boolean().optional(), }); export async function GET(request: Request) { const { searchParams } = new URL(request.url); const id = searchParams.get("id"); if (!id) { return new ChatbotError( "bad_request:api", "Parameter id is missing" ).toResponse(); } const session = await auth(); if (!session?.user) { return new ChatbotError("unauthorized:document").toResponse(); } const documents = await getDocumentsById({ id }); const [document] = documents; if (!document) { return new ChatbotError("not_found:document").toResponse(); } if (document.userId !== session.user.id) { return new ChatbotError("forbidden:document").toResponse(); } return Response.json(documents, { status: 200 }); } export async function POST(request: Request) { const { searchParams } = new URL(request.url); const id = searchParams.get("id"); if (!id) { return new ChatbotError( "bad_request:api", "Parameter id is required." ).toResponse(); } const session = await auth(); if (!session?.user) { return new ChatbotError("not_found:document").toResponse(); } let content: string; let title: string; let kind: ArtifactKind; let isManualEdit: boolean | undefined; try { const parsed = documentSchema.parse(await request.json()); content = parsed.content; title = parsed.title; kind = parsed.kind; isManualEdit = parsed.isManualEdit; } catch { return new ChatbotError( "bad_request:api", "Invalid request body." ).toResponse(); } const documents = await getDocumentsById({ id }); if (documents.length > 0) { const [doc] = documents; if (doc.userId !== session.user.id) { return new ChatbotError("forbidden:document").toResponse(); } } if (isManualEdit && documents.length > 0) { const result = await updateDocumentContent({ id, content }); return Response.json(result, { status: 200 }); } const document = await saveDocument({ id, content, title, kind, userId: session.user.id, }); return Response.json(document, { status: 200 }); } export async function DELETE(request: Request) { const { searchParams } = new URL(request.url); const id = searchParams.get("id"); const timestamp = searchParams.get("timestamp"); if (!id) { return new ChatbotError( "bad_request:api", "Parameter id is required." ).toResponse(); } if (!timestamp) { return new ChatbotError( "bad_request:api", "Parameter timestamp is required." ).toResponse(); } const session = await auth(); if (!session?.user) { return new ChatbotError("unauthorized:document").toResponse(); } const documents = await getDocumentsById({ id }); const [document] = documents; if (document.userId !== session.user.id) { return new ChatbotError("forbidden:document").toResponse(); } const parsedTimestamp = new Date(timestamp); if (Number.isNaN(parsedTimestamp.getTime())) { return new ChatbotError( "bad_request:api", "Invalid timestamp." ).toResponse(); } const documentsDeleted = await deleteDocumentsByIdAfterTimestamp({ id, timestamp: parsedTimestamp, }); return Response.json(documentsDeleted, { status: 200 }); }