Skip to content

feat: add global search for findings and reports (#1981)#2006

Open
SathvikaSingoti wants to merge 2 commits into
utksh1:mainfrom
SathvikaSingoti:feat/global-search-1981
Open

feat: add global search for findings and reports (#1981)#2006
SathvikaSingoti wants to merge 2 commits into
utksh1:mainfrom
SathvikaSingoti:feat/global-search-1981

Conversation

@SathvikaSingoti

Copy link
Copy Markdown
Collaborator

Description

Adds a global search feature for findings and reports, accessible from a search bar in the top navigation (both desktop and mobile).

Backend: New GET /api/v1/search?q={query}&limit={limit} endpoint in routes.py. Searches the caller's findings (by title/description) and reports (by name) using SQLite LIKE, scoped to owner_id per the existing BOLA-prevention pattern (issue #401) used throughout this file. User input is escaped against %/_/\ before being used in the LIKE pattern so literal wildcard characters in a search query can't produce unintended matches.

Frontend: New GlobalSearch component wired into AppShell's desktop top bar and mobile header. Input is debounced (300ms, via a new reusable useDebouncedValue hook) before calling the backend, and results render in a dropdown grouped by Findings/Reports. Clicking a result navigates to the relevant list page (Findings or Reports), no per-item detail route exists yet in the app, so this is the closest correct behavior today.

Restructured AppShell.tsx to add a shared top bar row (search) above <main> for desktop, while preserving the existing sidebar-offset layout behavior.Also documents the new endpoint in docs/API.md under a new "Search API" section, matching the existing per-endpoint format.

Related Issues

Closes #1981

Type of Change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • Added testing/backend/integration/test_search.py - 10 tests covering: missing/invalid query params, matching by finding title, matching by finding description, matching by report name, case-insensitivity, empty-result handling, LIKE wildcard escaping (%/_ treated as literal characters, not SQL wildcards), limit bounds enforcement, and owner-scoping (a finding belonging to another owner never appears in results).
  • Added frontend/testing/unit/components/GlobalSearch.test.tsx - covers initial render, debounce behavior (no call on empty query, call after typing), result rendering, no-results state, error state, navigation on result click, and closing the dropdown on Escape.
  • Ran ./testing/test_python.sh - new test file: 10/10 passing.
  • Ran npm run typecheck - clean.
  • Ran npm run test - 546/546 passing (including the two pre-existing AppShell.test.tsx sidebar-width tests, which needed the --sidebar-width CSS var re-applied directly to <main> after the layout restructure).
  • Ran npm run build - builds clean.
  • Ran bash scripts/check-artifacts.sh origin/main - no tracked generated artifacts or cache files in the diff.
  • Manually verified: typing in the search bar returns matching findings/reports, clicking a result navigates and clears the input, Escape closes the dropdown, clicking outside closes the dropdown.

Checklist

  • My code follows the code style of this project.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have made corresponding changes to the documentation.
  • My changes generate no new warnings.

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.

Feature: Global Search for Findings

1 participant