Skip to content

fix: Session search does an extra 2000-row listing pass on every query and still silently drops valid matches#777

Closed
sam-saffron-jarvis wants to merge 1 commit into
SamSaffron:mainfrom
sam-saffron-jarvis:feat/codereview-fe488782
Closed

fix: Session search does an extra 2000-row listing pass on every query and still silently drops valid matches#777
sam-saffron-jarvis wants to merge 1 commit into
SamSaffron:mainfrom
sam-saffron-jarvis:feat/codereview-fe488782

Conversation

@sam-saffron-jarvis

Copy link
Copy Markdown
Contributor

What changed

  • Reworked session FTS search to accept structured SearchOptions instead of a bare query/limit.
  • Pushed archived/category filtering into internal/session.SQLiteStore.Search(...) so SQLite filters before limiting.
  • Changed the SQLite search query to return one best match per session directly, instead of returning message-level duplicates and relying on handler-side deduping.
  • Expanded SearchResult with the session metadata the web handler needs, then removed the extra List(... Limit: 2000, SortByActivity: true) pass from handleSessionsSearch.
  • Added regressions for:
    • older matching sessions not being dropped once more than 2000 sessions exist
    • distinct-per-session search limiting and archived/category filtering in the store

Why this is high-value

The old /v1/sessions/search path did two DB queries per request:

  1. List(... Limit: 2000, SortByActivity: true) to build an allowlist map
  2. Search(query, limit*4) to get raw FTS hits, then dedupe/filter in Go

That was expensive on an interactive per-keystroke path, and it still produced incorrect results:

  • eligible matches older than the first 2000 listed sessions were silently excluded
  • repeated hits from one transcript could consume the limit*4 window before deduping, hiding other sessions

This change removes the extra listing pass entirely and lets SQLite return already-filtered, already-deduped session matches. That cuts handler work, avoids building a 2000-entry map on every search, reduces DB work from two queries to one in the hot path, and fixes the dropped-results bug.

Validation

  • gofmt -w internal/session/types.go internal/session/store.go internal/session/noop.go internal/session/sqlite.go internal/session/sqlite_test.go cmd/serve_handlers.go cmd/sessions.go cmd/serve_runtime_test.go internal/tui/sessions/browse.go internal/tui/sessions/browse_test.go cmd/serve_test.go
  • go build ./...
  • go test ./...
  • git diff --check

New coverage added:

  • TestHandleSessionsSearch_DoesNotDropOlderMatchesOutsideRecent2000ListWindow
  • TestSQLiteStoreSearchReturnsDistinctFilteredSessionMatches

@SamSaffron

Copy link
Copy Markdown
Owner

Integrated the session search optimization/fix into the main working copy; closing this PR.

@SamSaffron SamSaffron closed this Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants