diff --git a/src/app/api/notes/route.ts b/src/app/api/notes/route.ts index 260b717..7819f57 100644 --- a/src/app/api/notes/route.ts +++ b/src/app/api/notes/route.ts @@ -1,4 +1,6 @@ +import { notesIndex } from "@/lib/db/pinecone"; import prisma from "@/lib/db/prisma"; +import { getEmbedding } from "@/lib/openai"; import { createNoteSchema, deleteNoteSchema, @@ -25,12 +27,26 @@ export async function POST(req: Request) { return Response.json({ error: "Unauthorized" }, { status: 401 }); } - const note = await prisma.note.create({ - data: { - title, - content, - userId, - }, + const embedding = await getEmbeddingForNote(title, content); + + const note = await prisma.$transaction(async (tx) => { + const note = await tx.note.create({ + data: { + title, + content, + userId, + }, + }); + + await notesIndex.upsert([ + { + id: note.id, + values: embedding, + metadata: { userId }, + }, + ]); + + return note; }); return Response.json({ note }, { status: 201 }); @@ -65,12 +81,26 @@ export async function PUT(req: Request) { return Response.json({ error: "Unauthorized" }, { status: 401 }); } - const updatedNote = await prisma.note.update({ - where: { id }, - data: { - title, - content, - }, + const embedding = await getEmbeddingForNote(title, content); + + const updatedNote = await prisma.$transaction(async (tx) => { + const updatedNote = await tx.note.update({ + where: { id }, + data: { + title, + content, + }, + }); + + await notesIndex.upsert([ + { + id, + values: embedding, + metadata: { userId }, + }, + ]); + + return updatedNote; }); return Response.json({ updatedNote }, { status: 200 }); @@ -105,7 +135,10 @@ export async function DELETE(req: Request) { return Response.json({ error: "Unauthorized" }, { status: 401 }); } - await prisma.note.delete({ where: { id } }); + await prisma.$transaction(async (tx) => { + await tx.note.delete({ where: { id } }); + await notesIndex.deleteOne(id); + }); return Response.json({ message: "Note deleted" }, { status: 200 }); } catch (error) { @@ -113,3 +146,7 @@ export async function DELETE(req: Request) { return Response.json({ error: "Internal server error" }, { status: 500 }); } } + +async function getEmbeddingForNote(title: string, content: string | undefined) { + return getEmbedding(title + "\n\n" + content ?? ""); +} diff --git a/src/lib/openai.ts b/src/lib/openai.ts index 14929ce..aed8e50 100644 --- a/src/lib/openai.ts +++ b/src/lib/openai.ts @@ -9,3 +9,18 @@ if (!apiKey) { const openai = new OpenAI({ apiKey }); export default openai; + +export async function getEmbedding(text: string) { + const response = await openai.embeddings.create({ + model: "text-embedding-ada-002", + input: text, + }); + + const embedding = response.data[0].embedding; + + if (!embedding) throw Error("Error generating embedding."); + + console.log(embedding); + + return embedding; +}