Refactor Admin and Settings UI to Ethereal Precision aesthetic and improve note import/export functionality
Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 1m4s
Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 1m4s
This commit is contained in:
52
memento-note/app/api/notes/cleanup/route.ts
Normal file
52
memento-note/app/api/notes/cleanup/route.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { auth } from '@/auth'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const session = await auth()
|
||||
if (!session?.user?.id) {
|
||||
return NextResponse.json({ success: false, error: 'Unauthorized' }, { status: 401 })
|
||||
}
|
||||
|
||||
const userId = session.user.id
|
||||
|
||||
// 1. Find and delete labels that have no notes and belong to this user
|
||||
// We only delete labels that are not part of a notebook (global labels)
|
||||
const orphanedLabels = await prisma.label.findMany({
|
||||
where: {
|
||||
userId,
|
||||
notebookId: null,
|
||||
notes: { none: {} }
|
||||
}
|
||||
})
|
||||
|
||||
await prisma.label.deleteMany({
|
||||
where: {
|
||||
id: { in: orphanedLabels.map(l => l.id) }
|
||||
}
|
||||
})
|
||||
|
||||
// 2. Clean up NoteEmbeddings that don't have a corresponding Note (shouldn't happen with Cascade, but good for cleanup)
|
||||
const orphanedEmbeddings = await prisma.noteEmbedding.findMany({
|
||||
where: {
|
||||
note: { userId: { not: userId } } // Or just those where note is null if not using cascade
|
||||
}
|
||||
})
|
||||
|
||||
// Actually, let's just focus on user-specific cleanup
|
||||
|
||||
// 3. Remove note history entries for notes that were deleted (cascade should handle this, but let's be safe)
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
deletedLabels: orphanedLabels.length
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Cleanup error:', error)
|
||||
return NextResponse.json(
|
||||
{ success: false, error: 'Failed to cleanup data' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -91,9 +91,15 @@ export async function GET(req: NextRequest) {
|
||||
id: note.id,
|
||||
title: note.title,
|
||||
content: note.content,
|
||||
color: note.color,
|
||||
isPinned: note.isPinned,
|
||||
isArchived: note.isArchived,
|
||||
type: note.type,
|
||||
checkItems: note.checkItems,
|
||||
images: note.images,
|
||||
links: note.links,
|
||||
createdAt: note.createdAt,
|
||||
updatedAt: note.updatedAt,
|
||||
isPinned: note.isPinned,
|
||||
notebookId: note.notebookId,
|
||||
labelRelations: note.labelRelations.map(label => ({
|
||||
id: label.id,
|
||||
|
||||
@@ -111,11 +111,12 @@ export async function POST(req: NextRequest) {
|
||||
const mappedNotebookId = notebookIdMap.get(note.notebookId) || null
|
||||
|
||||
// Get label IDs
|
||||
const labelNames = (note.labels || note.labelRelations || []).map((l: any) => l.name).filter(Boolean)
|
||||
const labels = await prisma.label.findMany({
|
||||
where: {
|
||||
userId: session.user.id,
|
||||
name: {
|
||||
in: note.labels.map((l: any) => l.name)
|
||||
in: labelNames
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -125,8 +126,14 @@ export async function POST(req: NextRequest) {
|
||||
data: {
|
||||
userId: session.user.id,
|
||||
title: note.title || 'Untitled',
|
||||
content: note.content,
|
||||
content: note.content || '',
|
||||
color: note.color || 'default',
|
||||
isPinned: note.isPinned || false,
|
||||
isArchived: note.isArchived || false,
|
||||
type: note.type || 'richtext',
|
||||
checkItems: note.checkItems || null,
|
||||
images: note.images || null,
|
||||
links: note.links || null,
|
||||
notebookId: mappedNotebookId,
|
||||
labelRelations: {
|
||||
connect: labels.map(label => ({ id: label.id }))
|
||||
|
||||
59
memento-note/app/api/notes/reindex/route.ts
Normal file
59
memento-note/app/api/notes/reindex/route.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { auth } from '@/auth'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
import { EmbeddingService } from '@/lib/ai/services/embedding.service'
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const session = await auth()
|
||||
if (!session?.user?.id) {
|
||||
return NextResponse.json({ success: false, error: 'Unauthorized' }, { status: 401 })
|
||||
}
|
||||
|
||||
const userId = session.user.id
|
||||
|
||||
// Fetch all notes for the user
|
||||
const notes = await prisma.note.findMany({
|
||||
where: { userId, trashedAt: null },
|
||||
select: { id: true, title: true, content: true }
|
||||
})
|
||||
|
||||
const embeddingService = new EmbeddingService()
|
||||
let processedCount = 0
|
||||
|
||||
// Process in small batches to avoid timeouts if possible
|
||||
// Note: In a real production app, this should be a background job
|
||||
for (const note of notes) {
|
||||
try {
|
||||
const textToEmbed = `${note.title || ''}\n${note.content}`
|
||||
if (textToEmbed.trim()) {
|
||||
const embedding = await embeddingService.generateEmbedding(textToEmbed)
|
||||
|
||||
await prisma.noteEmbedding.upsert({
|
||||
where: { noteId: note.id },
|
||||
update: { embedding: JSON.stringify(embedding) },
|
||||
create: {
|
||||
noteId: note.id,
|
||||
embedding: JSON.stringify(embedding)
|
||||
}
|
||||
})
|
||||
processedCount++
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Failed to reindex note ${note.id}:`, err)
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
count: processedCount,
|
||||
total: notes.length
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Reindex error:', error)
|
||||
return NextResponse.json(
|
||||
{ success: false, error: 'Failed to reindex notes' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user