ihatebaselines's picture
Deploy Purcar gateway and local model engine
7e92e00 verified
Raw History Blame Contribute Delete
3.31 kB
import { NextRequest } from "next/server";
import { createAuthenticatedClient } from "@/lib/serverSupabase";
import { loadBuiltInKnowledge } from "@/lib/rag";
export const runtime = "nodejs";
function builtIns() {
return loadBuiltInKnowledge().map((document, index) => ({
id: `builtin-${index}`,
name: `${document.source}.md`,
slug: document.source,
sizeBytes: Buffer.byteLength(document.content),
words: document.content.split(/\s+/).length,
preview: document.content.slice(0, 180).replace(/\n/g, " "),
modifiedAt: null,
projectId: null,
builtIn: true,
}));
}
export async function GET(req: NextRequest) {
const base = builtIns();
const auth = await createAuthenticatedClient(req);
if (!auth) return Response.json({ files: base, authenticated: false });
const projectId = req.nextUrl.searchParams.get("projectId");
let query = auth.client.from("knowledge_documents").select("id,name,content,project_id,updated_at").order("updated_at", { ascending: false });
query = projectId ? query.or(`project_id.eq.${projectId},project_id.is.null`) : query.is("project_id", null);
const { data, error } = await query;
if (error) return Response.json({ files: base, authenticated: true, databaseReady: false, warning: error.message });
const privateFiles = (data || []).map((document) => ({
id: document.id,
name: document.name,
slug: document.name.replace(/\.(md|txt)$/i, ""),
sizeBytes: Buffer.byteLength(document.content),
words: document.content.split(/\s+/).length,
preview: document.content.slice(0, 180).replace(/\n/g, " "),
modifiedAt: document.updated_at,
projectId: document.project_id,
builtIn: false,
}));
return Response.json({ files: [...privateFiles, ...base], authenticated: true, databaseReady: true });
}
export async function POST(req: NextRequest) {
const auth = await createAuthenticatedClient(req);
if (!auth) return Response.json({ error: "Sign in to create private knowledge files." }, { status: 401 });
const { name, content, projectId = null } = await req.json();
if (!name?.trim() || !content?.trim()) return Response.json({ error: "Missing name or content" }, { status: 400 });
const safeName = name.trim().replace(/[^\p{L}\p{N}_. -]/gu, "_").slice(0, 120);
const { data, error } = await auth.client.from("knowledge_documents").insert({
owner_id: auth.user.id, project_id: projectId || null, name: /\.(md|txt)$/i.test(safeName) ? safeName : `${safeName}.md`, content: content.slice(0, 500000),
}).select("id,name").single();
if (error) return Response.json({ error: error.message, migrationRequired: error.code === "42P01" }, { status: 500 });
return Response.json({ success: true, file: data });
}
export async function DELETE(req: NextRequest) {
const auth = await createAuthenticatedClient(req);
if (!auth) return Response.json({ error: "Sign in required." }, { status: 401 });
const { id } = await req.json();
if (!id || String(id).startsWith("builtin-")) return Response.json({ error: "Built-in files cannot be deleted." }, { status: 400 });
const { error } = await auth.client.from("knowledge_documents").delete().eq("id", id);
if (error) return Response.json({ error: error.message }, { status: 500 });
return Response.json({ success: true });
}