From f7fd2221c8be9e65593fe9eadaf4a068e8698dcb Mon Sep 17 00:00:00 2001 From: Octopus Date: Thu, 9 Apr 2026 07:16:55 +0800 Subject: [PATCH] fix: rebuild FTS5 index after bulk observation import (fixes #1631) (#1632) Imported observations were invisible to the MCP search tool because the FTS5 content table was not reliably updated during bulk import. The import handler now calls rebuildObservationsFTSIndex() after inserting new observations, ensuring the full-text search index is consistent. A new SessionStore.rebuildObservationsFTSIndex() method encapsulates the FTS5 rebuild command and is a no-op when the observations_fts table does not exist (e.g. FTS5 unavailable on Windows). --- src/services/sqlite/SessionStore.ts | 17 +++++++++++++++++ src/services/worker/http/routes/DataRoutes.ts | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/src/services/sqlite/SessionStore.ts b/src/services/sqlite/SessionStore.ts index c5ece703..d7d853a7 100644 --- a/src/services/sqlite/SessionStore.ts +++ b/src/services/sqlite/SessionStore.ts @@ -2615,6 +2615,23 @@ export class SessionStore { return { imported: true, id: result.lastInsertRowid as number }; } + /** + * Rebuild the FTS5 index for observations. + * Should be called after bulk imports to ensure imported rows are searchable. + * No-op if observations_fts table does not exist. + */ + rebuildObservationsFTSIndex(): void { + const hasFTS = (this.db.prepare( + "SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'" + ).all() as { name: string }[]).length > 0; + + if (!hasFTS) { + return; + } + + this.db.run("INSERT INTO observations_fts(observations_fts) VALUES('rebuild')"); + } + /** * Import user prompt with duplicate checking * Duplicates are identified by content_session_id + prompt_number diff --git a/src/services/worker/http/routes/DataRoutes.ts b/src/services/worker/http/routes/DataRoutes.ts index 01013d5d..b476a3d9 100644 --- a/src/services/worker/http/routes/DataRoutes.ts +++ b/src/services/worker/http/routes/DataRoutes.ts @@ -391,6 +391,13 @@ export class DataRoutes extends BaseRouteHandler { stats.observationsSkipped++; } } + + // Rebuild FTS index so imported observations are immediately searchable. + // The FTS5 content table relies on triggers for incremental updates, but + // those triggers may not have fired correctly for all import paths. + if (stats.observationsImported > 0) { + store.rebuildObservationsFTSIndex(); + } } // Import prompts (depends on sessions)