feat(api): typeahead suggest endpoint for the global search box #56

Merged
KofTwentyTwo merged 3 commits from feature/typeahead-suggest into develop 2026-10-14 18:54:23 +00:00
KofTwentyTwo commented 2026-10-14 18:15:09 +00:00 (Migrated from github.com)

Summary

Adds GET /qqq/v1/qbit/quick-search/suggest as a second spec on the quick-search UI API extension (spec-generated contract in quick-search.yaml).

  • Prefix matches across indexed tables (the existing edge-ngram searchableText/field analyzers; no new index structure), top N per table (limitPerTable default 5, max 10), grouped per table (maxTables default 8, max 20, truncated), each item a record label plus subtitle. Optional tables filter.
  • Reuses QuickSearchAction, so it inherits table READ permission, record security locks, enabled-table filter, protected-PK tables and the PII/PHI exclusion from #55. No highlights, scores or display values leave the endpoint.
  • Fast and bounded: new QuickSearchInput.singlePass caps a locked per-table search to one candidate batch of 2x the page, never rescanning to fill gaps. Requires only a signed-in session (not admin). Term under 2 characters returns empty groups; over 100 is a 400; no runtime returns empty.
  • Debouncing is done by the Next UI (200 ms, aborting superseded requests); see the paired qqq-frontend-next PR.
  • Why not OpenSearch completion: the index already holds edge-ngram analyzed text (min 2, max 20) and a completion field would need a second index structure and a reindex for no gain over the existing prefix match.

Tests

495 unit tests and 44 integration tests (Testcontainers OpenSearch) pass with CI=true ./mvnw verify, including jacoco. New: grouping, limits, truncation, permission and lock exclusion, PHI/PII exclusion, short/long terms, no-runtime, contract test (two specs). Implemented with Codex, reviewed and verified by Claude.

Supersedes nothing: #40 (scores/highlights/totals for core record search) is separate and has been merged up to develop and un-drafted.

🤖 Generated with Claude Code

## Summary Adds `GET /qqq/v1/qbit/quick-search/suggest` as a second spec on the `quick-search` UI API extension (spec-generated contract in `quick-search.yaml`). - Prefix matches across indexed tables (the existing edge-ngram `searchableText`/field analyzers; no new index structure), top N per table (`limitPerTable` default 5, max 10), grouped per table (`maxTables` default 8, max 20, `truncated`), each item a record label plus subtitle. Optional `tables` filter. - Reuses `QuickSearchAction`, so it inherits table READ permission, record security locks, enabled-table filter, protected-PK tables and the PII/PHI exclusion from #55. No highlights, scores or display values leave the endpoint. - Fast and bounded: new `QuickSearchInput.singlePass` caps a locked per-table search to one candidate batch of 2x the page, never rescanning to fill gaps. Requires only a signed-in session (not admin). Term under 2 characters returns empty groups; over 100 is a 400; no runtime returns empty. - Debouncing is done by the Next UI (200 ms, aborting superseded requests); see the paired qqq-frontend-next PR. - Why not OpenSearch `completion`: the index already holds edge-ngram analyzed text (min 2, max 20) and a completion field would need a second index structure and a reindex for no gain over the existing prefix match. ## Tests 495 unit tests and 44 integration tests (Testcontainers OpenSearch) pass with `CI=true ./mvnw verify`, including jacoco. New: grouping, limits, truncation, permission and lock exclusion, PHI/PII exclusion, short/long terms, no-runtime, contract test (two specs). Implemented with Codex, reviewed and verified by Claude. Supersedes nothing: #40 (scores/highlights/totals for core record search) is separate and has been merged up to develop and un-drafted. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.