# PHASE 8: Search & Discovery **Status:** ⬜ Not Started **Estimated Time:** 8-10 hours **Priority:** HIGH **Depends On:** Phase 1 (Foundation), Phase 4 (Entity Services) **Blocks:** Phase 12 (Pages Migration) --- ## 🎯 Goal Migrate all search functionality from Supabase to Django's PostgreSQL full-text search with GIN indexes. --- ## 📋 Tasks ### Task 8.1: Search Service (3 hours) **File:** `src/services/search/searchService.ts` #### Create Core Service ```typescript class SearchService extends BaseService { // GET /search/?q={query} async globalSearch(query: string, filters?: SearchFilters): Promise // GET /search/parks/?q={query} async searchParks(query: string, filters?: ParkFilters): Promise // GET /search/rides/?q={query} async searchRides(query: string, filters?: RideFilters): Promise // GET /search/companies/?q={query} async searchCompanies(query: string, filters?: CompanyFilters): Promise // GET /search/ride-models/?q={query} async searchRideModels(query: string, filters?: RideModelFilters): Promise // GET /search/suggestions/?q={query} async getSearchSuggestions(query: string): Promise } ``` #### Checklist - [ ] Create `searchService.ts` with all methods - [ ] Create types for search results - [ ] Create mappers for search transformations - [ ] Handle search ranking/relevance - [ ] Implement debounced search - [ ] Export from `src/services/search/index.ts` --- ### Task 8.2: Update Search Components (2 hours) **File:** `src/components/search/SearchResults.tsx` #### Replace Supabase Calls ```typescript // OLD - Supabase const { data } = await supabase .from('parks') .select('*') .textSearch('name', query); // NEW - Django Service const parks = await searchService.searchParks(query, filters); ``` #### Checklist - [ ] Replace `supabase.textSearch()` with `searchService.globalSearch()` - [ ] Update search result display - [ ] Update search highlighting - [ ] Test search results rendering - [ ] Verify pagination works --- ### Task 8.3: Update Filter Components (3 hours) **Files to Update:** - `src/components/parks/ParkFilters.tsx` - `src/components/rides/RideFilters.tsx` - `src/components/manufacturers/ManufacturerFilters.tsx` - `src/components/operators/OperatorFilters.tsx` - `src/components/designers/DesignerFilters.tsx` #### Checklist - [ ] Replace all Supabase filter queries with service calls - [ ] Update park filters (type, location, status) - [ ] Update ride filters (category, manufacturer, status) - [ ] Update company filters (type, country) - [ ] Test all filter combinations - [ ] Verify filter state persistence --- ### Task 8.4: Search Autocomplete (2 hours) **File:** `src/components/search/SearchAutocomplete.tsx` #### Create/Update Autocomplete - [ ] Implement search suggestions - [ ] Debounce search input - [ ] Display recent searches - [ ] Handle keyboard navigation - [ ] Test autocomplete behavior --- ## 🎯 Success Criteria ### Service Layer - [ ] SearchService created and functional - [ ] All search operations use service - [ ] Search ranking works correctly - [ ] Suggestions work ### Components - [ ] Zero `supabase.textSearch()` calls - [ ] Zero `supabase.from().ilike()` calls for search - [ ] All filter components updated - [ ] Search results display correctly - [ ] Autocomplete works ### Testing - [ ] Global search works - [ ] Entity-specific search works - [ ] Filters work correctly - [ ] Search rankings are relevant - [ ] Autocomplete suggests correctly - [ ] Empty search handled gracefully - [ ] No results handled gracefully ### Performance - [ ] Search is fast (<500ms) - [ ] Debouncing prevents excessive requests - [ ] Results are properly cached - [ ] Pagination works smoothly --- ## 📝 Implementation Notes ### Django Search Implementation - Django uses PostgreSQL GIN indexes for full-text search - Search vectors are automatically updated via signals - Ranking is handled by PostgreSQL `ts_rank` - Supports phrase search, AND/OR operators - Accent-insensitive search ### Search Features - **Global Search**: Searches across all entity types - **Entity Search**: Searches within specific entity type - **Filters**: Can be combined with search queries - **Ranking**: Results sorted by relevance - **Highlighting**: Search terms highlighted in results ### Debouncing - Implement 300ms debounce on search input - Cancel previous search requests - Show loading state during search - Cache recent search results ### Empty States - Handle empty search query - Handle no results found - Suggest alternative spellings - Show recent searches --- ## 🔗 Related Files ### Services - `src/services/search/searchService.ts` - `src/services/search/types.ts` - `src/services/search/mappers.ts` ### Components - `src/components/search/SearchResults.tsx` - `src/components/search/SearchAutocomplete.tsx` - `src/components/search/SearchFilters.tsx` - All filter components in entity directories ### Hooks - `src/hooks/useSearch.ts` - `src/hooks/useSearchFilters.ts` - `src/hooks/useSearchSuggestions.ts` --- ## ⏭️ Next Phase **Phase 9:** Timeline & History - Migrate timeline events and entity history to Django.