mirror of
https://github.com/bretzel-app/crumbs.git
synced 2026-10-12 20:06:57 +02:00
- Batch-fetch tags for notes in a single query instead of per-note loops - Add composite indexes on notes, note_tags, and sync_log tables - Wrap sync push in a transaction for atomicity - Replace O(n) cleanExpiredSessions with single DELETE query - Use SQL WHERE in getChangesSince instead of loading all notes - Extract shared syncNoteTags utility to eliminate duplication - Add root +error.svelte boundary matching app theme Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
59 lines
1.4 KiB
TypeScript
59 lines
1.4 KiB
TypeScript
import { json } from '@sveltejs/kit';
|
|
import type { RequestHandler } from './$types.js';
|
|
import { db } from '$lib/server/db/index.js';
|
|
import { notes, noteTags, tags } from '$lib/server/db/schema.js';
|
|
import { and, eq, like, or, inArray } from 'drizzle-orm';
|
|
import { fetchTagsForNotes } from '$lib/server/tags.js';
|
|
|
|
export const GET: RequestHandler = async ({ url }) => {
|
|
const query = url.searchParams.get('q')?.trim();
|
|
|
|
if (!query) {
|
|
return json([]);
|
|
}
|
|
|
|
const pattern = `%${query}%`;
|
|
|
|
const results = db
|
|
.select()
|
|
.from(notes)
|
|
.where(
|
|
and(
|
|
eq(notes.trashed, false),
|
|
or(like(notes.title, pattern), like(notes.content, pattern))
|
|
)
|
|
)
|
|
.all();
|
|
|
|
// Also search by tag name
|
|
const tagResults = db
|
|
.select({ noteId: noteTags.noteId })
|
|
.from(noteTags)
|
|
.innerJoin(tags, eq(noteTags.tagId, tags.id))
|
|
.where(like(tags.name, pattern))
|
|
.all();
|
|
|
|
const resultIds = new Set(results.map((n) => n.id));
|
|
const extraNoteIds = [...new Set(tagResults.map((r) => r.noteId))].filter(
|
|
(id) => !resultIds.has(id)
|
|
);
|
|
|
|
let extraNotes: typeof results = [];
|
|
if (extraNoteIds.length > 0) {
|
|
extraNotes = db
|
|
.select()
|
|
.from(notes)
|
|
.where(and(inArray(notes.id, extraNoteIds), eq(notes.trashed, false)))
|
|
.all();
|
|
}
|
|
|
|
const combined = [...results, ...extraNotes];
|
|
const tagMap = fetchTagsForNotes(combined.map((n) => n.id));
|
|
const withTags = combined.map((note) => ({
|
|
...note,
|
|
tags: tagMap.get(note.id) ?? []
|
|
}));
|
|
|
|
return json(withTags);
|
|
};
|