- Create SearchService with SearchMediaItemsUnified method
- Add SearchFieldValues method for autocomplete dropdown population
- Add parseSearchQuery helper for quote detection (exact vs fuzzy search)
- Move all business logic from handler to service layer
- Follow established service pattern (FiltersService, CollectionService)
- Service created inside handler constructor, not in main.go
- SearchParams struct supports all filter types + sort parameter
- FieldSearchParams struct for field-specific autocomplete queries
- Returns FieldValue results with count and similarity scores
This provides a clean service layer abstraction for search operations.
Create new SearchService to encapsulate all search business logic:
Features:
- Unified search combining text search with filters
- Fuzzy matching using pg_trgm word_similarity (threshold: 0.3)
- Exact search when query is wrapped in quotes
- Field-specific autocomplete for dropdowns (author, genre, series, language)
- Proper pagination with configurable limit/offset
Implementation details:
- SearchMediaItems: Routes to SearchMediaItemsUnified query
* Detects exact search by checking for quotes in query
* Builds search pattern for ILIKE matching (%term%)
* Converts string filters to pgtype.Text with proper Valid flags
- SearchFieldValues: Routes to appropriate field-specific query
* Uses switch statement to call correct query based on field_type
* Returns []FieldValue with value, count, and similarity score
* Handles all 4 field types: author, genre, series, language
Design pattern: Service layer separates business logic from handlers,
following project's established architecture (FiltersService, CollectionService).