# S04 Research — Search Autocomplete & Suggestions

## Summary

This is **light research**. The codebase already has a working typeahead dropdown on Home.tsx (debounced 300ms, shows top 5 results after 2+ chars). The slice adds two features: (1) show popular/suggested terms when the empty search box is focused, and (2) bring the same autocomplete experience to the SearchResults page. All infrastructure exists — this is UI wiring plus one lightweight backend endpoint.

## Requirement Coverage

- **R005 (Search-First Web UI)** — already validated. This slice polishes the search interaction.
- **R015 (30-Second Retrieval Target)** — active. Autocomplete and popular suggestions directly reduce time-to-first-result.

## Recommendation

Build a lightweight `/api/v1/search/suggestions` endpoint that returns popular search terms (derived from technique page titles, topic tags, and sub-topic names ranked by technique count). Frontend changes: extract the typeahead dropdown into a shared component, add popular-suggestions-on-focus to both Home.tsx and SearchResults.tsx.

## Implementation Landscape

### What Exists

| Component | File | State |
|---|---|---|
| Search API endpoint | `backend/routers/search.py` | Working — `GET /search?q=&scope=&limit=` |
| Search service (semantic + keyword) | `backend/search_service.py` | Working — embed → Qdrant → keyword fallback |
| Search schemas | `backend/schemas.py` lines 204-224 | `SearchResultItem`, `SearchResponse` |
| API client | `frontend/src/api/public-client.ts` | `searchApi()` function |
| Home page typeahead | `frontend/src/pages/Home.tsx` | Debounced 300ms, 5 results after 2+ chars, dropdown with outside-click dismiss |
| Popular topics on home | `frontend/src/pages/Home.tsx` | Already loads top-8 sub-topics by technique_count — displayed as pills |
| SearchResults page | `frontend/src/pages/SearchResults.tsx` | Has search input but NO typeahead dropdown, no suggestions |
| Typeahead CSS | `frontend/src/App.css` lines 1060-1135 | `.typeahead-dropdown`, `.typeahead-item`, `.typeahead-see-all` all styled |
| Tests | `backend/tests/test_search.py` | Integration tests for search endpoint with mocked SearchService |

### What's Missing

1. **No suggestions endpoint** — nothing returns popular terms for an empty search box
2. **No shared typeahead component** — Home.tsx has the dropdown inline, SearchResults.tsx lacks it entirely
3. **No empty-focus behavior** — when input is focused but empty, dropdown doesn't appear

### Backend: Suggestions Endpoint

A new `GET /api/v1/search/suggestions` endpoint that returns a list of suggested search terms. These can be derived from:
- Top technique page titles (by view_count or just most recent)
- Popular sub-topic names (by technique_count — already computed in topics router)
- Creator names

No Redis caching needed for now — a simple DB query hitting TechniquePage and the canonical tags YAML is fast enough. The response is a small list (8-12 items) that changes rarely.

Schema: `{ suggestions: [{ text: string, type: "topic" | "technique" | "creator" }] }`

### Frontend: Shared Autocomplete Component

Extract the typeahead logic from Home.tsx into a reusable `SearchAutocomplete` component:
- Props: `onSearch(query)`, `placeholder`, `heroSize?: boolean`
- State: query, suggestions (search results), popularTerms, showDropdown
- Behavior:
  - **Focus + empty query** → show popular suggestions (fetched once on mount)
  - **2+ chars** → show search results (existing debounced behavior)
  - **Escape** → close
  - **Outside click** → close
  - **Enter** → navigate to `/search?q=...`
  - **Arrow keys** → keyboard navigation through dropdown items (nice-to-have)

Then use it in both `Home.tsx` and `SearchResults.tsx`.

### CSS

Existing typeahead CSS covers the dropdown styling. May need:
- A `.typeahead-suggestions` section for popular terms (slightly different styling — maybe a header label "Popular" or "Try searching for...")
- Keyboard-selected state (`.typeahead-item--active`) if arrow key nav is added

### Natural Seams for Task Decomposition

1. **Backend: suggestions endpoint** — new route in `backend/routers/search.py`, new schema in `schemas.py`, integration test. Independent of frontend.
2. **Frontend: extract SearchAutocomplete component** — pull typeahead out of Home.tsx into `components/SearchAutocomplete.tsx`, wire it into both Home.tsx and SearchResults.tsx, add popular-suggestions-on-focus. This depends on task 1 (needs the API client function for suggestions).
3. **Verification** — build check, manual browser verification on running app.

Tasks 1 and 2 are the core work. Task 2 is larger (component extraction + two page integrations + CSS additions).

### Risks

- **Low risk.** All patterns established. The typeahead UI exists — we're extracting it and adding an empty-state feature.
- The only non-trivial part is making arrow-key navigation work cleanly in the dropdown. If it adds too much complexity, ship without it — mouse/touch works fine.

### Verification Strategy

- `npm run build` passes with zero TypeScript errors
- Backend tests pass (existing + new suggestions endpoint test)
- Browser: focus empty search on Home → popular suggestions appear in dropdown
- Browser: type 2+ chars → search results appear
- Browser: SearchResults page has the same autocomplete behavior
