mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 10:31:13 -05:00
198 lines
5.1 KiB
Markdown
198 lines
5.1 KiB
Markdown
# 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<SearchResults>
|
|
|
|
// GET /search/parks/?q={query}
|
|
async searchParks(query: string, filters?: ParkFilters): Promise<Park[]>
|
|
|
|
// GET /search/rides/?q={query}
|
|
async searchRides(query: string, filters?: RideFilters): Promise<Ride[]>
|
|
|
|
// GET /search/companies/?q={query}
|
|
async searchCompanies(query: string, filters?: CompanyFilters): Promise<Company[]>
|
|
|
|
// GET /search/ride-models/?q={query}
|
|
async searchRideModels(query: string, filters?: RideModelFilters): Promise<RideModel[]>
|
|
|
|
// GET /search/suggestions/?q={query}
|
|
async getSearchSuggestions(query: string): Promise<string[]>
|
|
}
|
|
```
|
|
|
|
#### 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.
|