fix: brainstorm infinite loop, ghost cursor, embedding ::vector cast, semantic search, billing stats, usage meter accordion
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 5s

- Fix useBrainstormSocket: stable guestId via useRef, remove setState in cleanup
- Fix GhostCursor: direct DOM manipulation via refs, no useState re-renders
- Fix all SQL embedding queries: add ::vector cast on text columns
- Fix embedding truncation to 15000 chars (under 8192 token limit)
- Fix NoteEmbedding INSERT: remove non-existent updatedAt column
- Fix billing page: show all quota stats in grid instead of single metric
- Fix usage meter: accordion expand/collapse, per-feature detail
- Fix semantic search: rebuild 103 note embeddings, ::vector cast on vectorSearch
- Fix brainstorm expand/manual-idea/create: ::vector cast on embedding SQL
This commit is contained in:
Antigravity
2026-05-16 18:50:34 +00:00
parent ee8e2bda59
commit 8c7ca69640
117 changed files with 11732 additions and 834 deletions

View File

@@ -434,7 +434,7 @@ export async function restoreNoteVersion(noteId: string, historyEntryId: string)
},
})
revalidatePath('/')
revalidatePath('/home')
return parseNote(restored)
}
@@ -603,7 +603,7 @@ export async function createNote(data: {
if (!data.skipRevalidation) {
// Revalidate main page (handles both inbox and notebook views via query params)
revalidatePath('/')
revalidatePath('/home')
}
// Fire-and-forget: run AI operations in background without blocking the response
@@ -690,7 +690,7 @@ export async function createNote(data: {
const merged = [...new Set([...existingNames, ...appliedLabels])]
await syncNoteLabels(noteId, merged, notebookId ?? null, userId)
if (!data.skipRevalidation) {
revalidatePath('/')
revalidatePath('/home')
}
}
}
@@ -853,7 +853,7 @@ export async function updateNote(id: string, data: {
if (!options?.skipRevalidation) {
try { revalidatePath(`/note/${id}`) } catch {}
try { revalidatePath('/') } catch {}
try { revalidatePath('/home') } catch {}
}
if (isStructuralChange) {
@@ -895,7 +895,7 @@ export async function deleteNote(id: string, options?: { skipRevalidation?: bool
})
if (!options?.skipRevalidation) {
revalidatePath('/')
revalidatePath('/home')
}
return { success: true }
} catch (error) {
@@ -915,7 +915,7 @@ export async function trashNote(id: string, options?: { skipRevalidation?: boole
data: { trashedAt: new Date() }
})
if (!options?.skipRevalidation) {
revalidatePath('/')
revalidatePath('/home')
}
return { success: true }
} catch (error) {
@@ -933,7 +933,7 @@ export async function restoreNote(id: string) {
where: { id, userId: session.user.id },
data: { trashedAt: null }
})
revalidatePath('/')
revalidatePath('/home')
revalidatePath('/trash')
return { success: true }
} catch (error) {
@@ -984,7 +984,7 @@ export async function permanentDeleteNote(id: string) {
await syncLabels(session.user.id, [])
revalidatePath('/trash')
revalidatePath('/')
revalidatePath('/home')
return { success: true }
} catch (error) {
console.error('Error permanently deleting note:', error)
@@ -1028,7 +1028,7 @@ export async function emptyTrash() {
await syncLabels(session.user.id, [])
revalidatePath('/trash')
revalidatePath('/')
revalidatePath('/home')
return { success: true }
} catch (error) {
console.error('Error emptying trash:', error)
@@ -1182,7 +1182,7 @@ export async function reorderNotes(draggedId: string, targetId: string) {
prisma.note.update({ where: { id: note.id }, data: { order: index } })
)
await prisma.$transaction(updates)
revalidatePath('/')
revalidatePath('/home')
return { success: true }
} catch (error) {
throw new Error('Failed to reorder notes')
@@ -1198,7 +1198,7 @@ export async function updateFullOrder(ids: string[]) {
prisma.note.update({ where: { id, userId }, data: { order: index } })
)
await prisma.$transaction(updates)
revalidatePath('/')
revalidatePath('/home')
return { success: true }
} catch (error) {
throw new Error('Failed to update order')
@@ -1314,7 +1314,7 @@ export async function cleanupAllOrphans() {
}
}
revalidatePath('/')
revalidatePath('/home')
revalidatePath('/settings')
return {
success: true,
@@ -1487,7 +1487,7 @@ export async function dismissFromRecent(id: string) {
data: { dismissedFromRecent: true }
})
// revalidatePath('/') // Removed to prevent immediate refill of the list
// revalidatePath('/home') // Removed to prevent immediate refill of the list
return { success: true }
} catch (error) {
console.error('Error dismissing note from recent:', error)
@@ -1895,7 +1895,7 @@ export async function respondToShareRequest(shareId: string, action: 'accept' |
});
// Revalidate all relevant cache tags
revalidatePath('/');
revalidatePath('/home');
return { success: true, share: updatedShare };
} catch (error: any) {
@@ -1957,7 +1957,7 @@ export async function removeSharedNoteFromView(shareId: string) {
}
});
revalidatePath('/');
revalidatePath('/home');
return { success: true };
} catch (error: any) {
console.error('Error removing shared note from view:', error);
@@ -2018,7 +2018,7 @@ export async function leaveSharedNote(noteId: string) {
}
});
revalidatePath('/');
revalidatePath('/home');
return { success: true };
} catch (error: any) {
console.error('Error leaving shared note:', error);