php artisan migrateThis creates:
search_historiestable- Adds search fields to
productstable - Adds clothing attributes to
productstable - Creates all necessary indexes
Already added to bootstrap/providers.php. Verify by checking:
App\Providers\SearchServiceProvider::class,# Search products
curl "http://localhost:8000/api/v1/search/products?query=hijab"
# Autocomplete
curl "http://localhost:8000/api/v1/search/autocomplete?query=hij"
# Vendor search
curl "http://localhost:8000/api/v1/vendors/1/search?query=abaya"- Enums (FabricTypeEnum, SleeveLengthEnum, OpacityLevelEnum, HijabStyleEnum, SortOptionEnum)
- DTOs (ProductSearchDTO, AutocompleteDTO)
- Service Layer
- SearchService (main orchestrator)
- ProductSearchQueryBuilder
- FilterService
- SortService
- SearchHistoryService
- SearchSuggestionService
- Service Provider (SearchServiceProvider)
- Models
- SearchHistory model
- Product model (updated with new fields)
- API Resources
- ProductSearchResource
- SearchSuggestionResource
- SearchHistoryResource
- Controllers
- SearchController (global search)
- VendorSearchController
- Routes
- Product module routes
- Vendor module routes
- Migrations (3 total)
- Tests
- Feature tests
- API tests
- History tests
- Console Commands
- PruneSearchHistory command
- Documentation
-
Seed test data:
php artisan tinker # Create vendors Modules\Vendor\Models\Vendor::factory(5)->create(); # Create categories Modules\Category\Models\Category::factory(10)->create(); # Create products with search fields Modules\Product\Models\Product::factory(100)->create();
-
Run tests:
php artisan test tests/Feature/SearchFeatureTest.php php artisan test tests/Feature/Api/SearchApiTest.php php artisan test tests/Feature/SearchHistoryTest.php
-
Update Product Filament form to include new fields:
- keywords
- clothing_attributes
- sales_count (read-only)
- avg_rating (read-only)
- rating_count (read-only)
-
Schedule search history pruning:
// app/Console/Kernel.php protected function schedule(Schedule $schedule) { $schedule->command('search:prune-history')->daily(); }
-
Add environment configuration (optional):
SEARCH_CACHE_DURATION=60 SEARCH_AUTOCOMPLETE_LIMIT=10 SEARCH_RESULTS_PER_PAGE=20
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/search/products |
Search all products |
| GET | /api/v1/search/cursor |
Cursor-based search (infinite scroll) |
| GET | /api/v1/search/autocomplete |
Get suggestions |
| GET | /api/v1/vendors/{id}/search |
Search vendor store |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/search/history |
Get user's search history |
| DELETE | /api/v1/search/history |
Clear all history |
| DELETE | /api/v1/search/history/{id} |
Delete single entry |
curl "http://localhost:8000/api/v1/search/products?query=hijab&sort=popularity"curl "http://localhost:8000/api/v1/search/products\
?query=hijab\
&category_id=2\
&price_min=10\
&price_max=50\
&fabric_type=cotton\
&sort=price_asc\
&per_page=20"curl "http://localhost:8000/api/v1/vendors/5/search?query=abaya&sort=newest"curl "http://localhost:8000/api/v1/search/autocomplete\
?query=hij\
&limit=10"# Get history
curl -H "Authorization: Bearer TOKEN" \
"http://localhost:8000/api/v1/search/history?limit=20"
# Clear history
curl -X DELETE \
-H "Authorization: Bearer TOKEN" \
"http://localhost:8000/api/v1/search/history"Customize these constants:
const MAX_PER_PAGE = 100;
const DEFAULT_PER_PAGE = 20;
const HISTORY_LIMIT = 50;
const HISTORY_RETENTION_DAYS = 90;
const AUTOCOMPLETE_CACHE_MINUTES = 60;
const POPULAR_SEARCHES_CACHE_MINUTES = 1440;All necessary indexes are created by migrations. To verify:
php artisan tinker
DB::select('SHOW INDEX FROM products')
DB::select('SHOW INDEX FROM search_histories')The system uses:
- Full-text search on name, description, keywords
- Composite indexes for common filter combinations
- Eager loading to prevent N+1 queries
- Cursor pagination for efficient offset-less traversal
- Autocomplete results: 60 minutes
- Popular searches: 24 hours
- Search history: Real-time (not cached)
When ready to migrate to full-text search engine:
- Install Scout and Meilisearch
- Replace
ProductSearchQueryBuilder::applyTextSearch()with Scout calls - Update filters to use Meilisearch filters API
- Use facets for better filtering UI
- Create new QueryBuilder class implementing same interface
- Update ProductSearchService to use new builder
- Add feature flags to switch between implementations
-
Verify full-text index exists:
SHOW INDEX FROM products WHERE Key_name = 'idx_fulltext';
-
Check if products have
status = 'active' -
Try fallback LIKE search:
$results = app(SearchService::class)->getAutocompleteFallback('query');
-
Check index usage:
EXPLAIN SELECT * FROM products WHERE MATCH(name) AGAINST('+term*' IN BOOLEAN MODE);
-
Verify indexes are built:
php artisan migrate
-
Monitor slow query log:
SET GLOBAL slow_query_log = 'ON';
-
Verify authentication:
auth()->check() // Should return true
-
Check table exists:
php artisan migrate
-
Verify service is registered:
app(SearchHistoryService::class) // Should work
app/
├── DTOs/
│ ├── ProductSearchDTO.php
│ └── AutocompleteDTO.php
├── Enums/
│ ├── FabricTypeEnum.php
│ ├── SleeveLengthEnum.php
│ ├── OpacityLevelEnum.php
│ ├── HijabStyleEnum.php
│ └── SortOptionEnum.php
├── Models/
│ └── SearchHistory.php
├── Providers/
│ └── SearchServiceProvider.php
├── Services/Search/
│ ├── SearchService.php
│ ├── ProductSearchQueryBuilder.php
│ ├── FilterService.php
│ ├── SortService.php
│ ├── SearchHistoryService.php
│ └── SearchSuggestionService.php
├── Support/Search/
│ └── SearchConfig.php
├── Console/Commands/
│ └── PruneSearchHistory.php
└── Http/Resources/
└── SearchHistoryResource.php
Modules/Product/Http/
├── Controllers/Api/
│ └── SearchController.php
└── Resources/
├── ProductSearchResource.php
└── SearchSuggestionResource.php
Modules/Vendor/Http/Controllers/Api/
└── VendorSearchController.php
database/migrations/
├── 2025_01_16_000001_create_search_histories_table.php
├── 2025_01_16_000002_add_search_fields_to_products.php
└── 2025_01_16_000003_add_clothing_attributes_to_products.php
tests/Feature/
├── SearchFeatureTest.php
├── SearchHistoryTest.php
└── Api/SearchApiTest.php
For issues or questions:
- Check SEARCH_DOCUMENTATION.md for detailed API docs
- Review service implementations in app/Services/Search/
- Check test files for usage examples
- Review migrations for database schema