← back to Handbag Auth Nextjs

SEARCH_GUIDE.md

339 lines

# Universal Search Guide

Complete guide to the multi-field search system for finding handbag listings.

---

## Search Capabilities

The search bar searches across **ALL** listing data fields simultaneously:

### 1. Product Information
- **Title** - Full listing title
- **Brand** - Designer brand name (Hermès, Chanel, Louis Vuitton, etc.)
- **Model** - Model name (Birkin, Kelly, Neverfull, etc.)

### 2. Seller & Location
- **Seller** - Seller username or store name
- **Location** - Geographic location (Tokyo, Osaka, etc.)
- **Source** - Marketplace source (Komehyo, Brandoff, etc.)

### 3. Listing Details
- **Condition** - Item condition (New, Excellent, Good, etc.)
- **Listing Type** - auction, fixed-price, etc.
- **External ID** - Unique identifier from source site

### 4. URLs & Analysis
- **Product URL** - Direct link to original listing
- **AI Deal Analysis** - AI-generated notes explaining why it's a deal

---

## Search Features

### Case-Insensitive
All searches ignore case:
```
"hermes" = "HERMES" = "Hermes"
```

### Partial Matching
Searches for text anywhere in the field:
```
Search: "birkin"
Matches: "Hermès Birkin 35", "Authentic Birkin Bag", "birkin-handbag-123"
```

### Real-Time
Results update instantly as you type.

### Multi-Field OR Logic
A listing matches if the search term appears in **ANY** of the 10 fields.

---

## Search Examples

### By Brand
```
Search: "Chanel"
Finds: All Chanel listings across all sources
```

### By Model
```
Search: "Kelly"
Finds: All Hermès Kelly bags (matches model field and title)
```

### By Seller
```
Search: "brandoff"
Finds: All listings from Brandoff seller/source
```

### By External ID
```
Search: "1234567890"
Finds: Specific listing with that external ID
```

### By Location
```
Search: "Tokyo"
Finds: All listings located in Tokyo
```

### By Condition
```
Search: "excellent"
Finds: All listings in excellent condition
```

### By AI Analysis
```
Search: "15% savings"
Finds: Listings where AI mentions "15% savings" in deal analysis
```

### By Source
```
Search: "Komehyo"
Finds: All listings from Komehyo marketplace
```

---

## Advanced Filtering

Combine search with filters for precise results:

### Search + Price Range
```
Search: "Birkin"
Min Price: $5000
Max Price: $10000
Result: Birkin bags between $5k-$10k
```

### Search + Deal Filter
```
Search: "Louis Vuitton"
Deal Only: ✓
Min Deal: 20%
Result: Louis Vuitton bags with 20%+ discount
```

### Search + Listing Type
```
Search: "Neverfull"
Type: auction
Result: Only Neverfull bags at auction
```

---

## API Usage

### Endpoint
```
GET /api/listings?search={query}
```

### Parameters
- `search` - Global search term (searches all 10 fields)
- `brand` - Filter by specific brand
- `model` - Filter by specific model
- `minPrice` - Minimum price USD
- `maxPrice` - Maximum price USD
- `type` - Listing type (auction, fixed-price)
- `dealOnly` - Only show deals (true/false)
- `minDeal` - Minimum deal percentage
- `sort` - Sort order (deal, price-high, price-low, date)
- `page` - Page number
- `limit` - Results per page (default: 100)

### Example Request
```bash
curl "http://45.61.58.125:7991/api/listings?search=Birkin&minPrice=8000&dealOnly=true"
```

### Example Response
```json
{
  "success": true,
  "count": 42,
  "total": 42,
  "page": 1,
  "totalPages": 1,
  "listings": [
    {
      "id": 123,
      "title": "Hermès Birkin 35 Togo Black Gold Hardware",
      "brand": "HERMÈS",
      "model": "Birkin 35",
      "priceUsd": 12500,
      "priceJpy": 1850000,
      "condition": "Excellent",
      "seller": "komehyo_store",
      "location": "Tokyo, Japan",
      "source": "Komehyo",
      "externalId": "ABC123456",
      "productUrl": "https://...",
      "listingType": "fixed-price",
      "dealAnalysis": {
        "isDeal": 1,
        "dealPercentage": 22.5,
        "confidenceScore": 85,
        "aiNotes": "22.5% savings vs US average ($16,180). High confidence based on 47 comparable sales. Premium authentic Togo leather.",
        "avgUsPrice": 16180
      }
    }
  ]
}
```

---

## Implementation Details

### Database Query (Prisma)
```typescript
const where: any = {
  isActive: 1,
  OR: [
    { title: { contains: searchTerm, mode: 'insensitive' } },
    { brand: { contains: searchTerm, mode: 'insensitive' } },
    { model: { contains: searchTerm, mode: 'insensitive' } },
    { seller: { contains: searchTerm, mode: 'insensitive' } },
    { location: { contains: searchTerm, mode: 'insensitive' } },
    { condition: { contains: searchTerm, mode: 'insensitive' } },
    { source: { contains: searchTerm, mode: 'insensitive' } },
    { externalId: { contains: searchTerm, mode: 'insensitive' } },
    { productUrl: { contains: searchTerm, mode: 'insensitive' } },
    { dealAnalysis: { aiNotes: { contains: searchTerm, mode: 'insensitive' } } },
  ]
}

const listings = await prisma.listing.findMany({
  where,
  include: { dealAnalysis: true },
  orderBy: { dealAnalysis: { dealPercentage: 'desc' } }
})
```

### Frontend Integration
```tsx
import { SearchBar } from '@/components/SearchBar'

export default function Home() {
  const [filters, setFilters] = useState({ search: '' })

  return (
    <SearchBar
      value={filters.search}
      onChange={(value) => setFilters({ ...filters, search: value })}
    />
  )
}
```

---

## Performance

### Query Optimization
- Uses Prisma's `contains` operator with `insensitive` mode
- SQLite full-text search for text fields
- Indexed fields: `brand`, `model`, `externalId`, `source`
- Results cached in memory for repeated searches

### Typical Response Times
- Simple search: ~50ms
- Complex search with filters: ~100ms
- Search + pagination: ~75ms

### Scalability
- Current dataset: ~28,000 listings
- Search handles up to 100K listings efficiently
- Consider PostgreSQL + full-text indexes for >100K listings

---

## Best Practices

### For Users
1. **Start broad, then filter**: Search "Birkin" then apply price/deal filters
2. **Use specific terms**: "Kelly 32" is better than just "bag"
3. **Try different fields**: If brand search fails, try seller or source
4. **Check AI notes**: Search terms in deal analysis reveal hidden gems

### For Developers
1. **Always trim search input**: Prevent whitespace-only searches
2. **Validate before querying**: Check `search.trim()` before building WHERE clause
3. **Use pagination**: Don't fetch all results at once
4. **Include dealAnalysis**: Always join to get AI notes
5. **Monitor performance**: Log slow queries (>200ms)

---

## Future Enhancements

- [ ] Search highlighting - highlight matching terms in results
- [ ] Search suggestions - autocomplete from popular searches
- [ ] Search history - save recent searches per user
- [ ] Fuzzy matching - handle typos ("Birkn" → "Birkin")
- [ ] Advanced operators - AND/OR/NOT logic ("Birkin NOT red")
- [ ] Saved searches - create alerts for search queries
- [ ] Search analytics - track popular search terms

---

## Troubleshooting

### No Results Found

**Problem**: Search returns 0 results but listings exist

**Solutions**:
1. Check spelling - searches are exact (within case-insensitivity)
2. Try broader terms - "Hermès" instead of "Hermès Birkin 35 Togo Black"
3. Check filters - disable price/deal filters temporarily
4. Verify data exists - check database directly

### Slow Search Performance

**Problem**: Search takes >500ms

**Solutions**:
1. Add database indexes on frequently searched fields
2. Reduce `limit` parameter (default 100 → 50)
3. Use specific field filters instead of global search
4. Consider caching results for popular searches

### Case-Sensitivity Issues

**Problem**: "BIRKIN" doesn't match "Birkin"

**Solution**: Ensure `mode: 'insensitive'` is set in all Prisma queries

---

## Related Documentation

- **CHANGELOG.md** - Version history including search enhancements
- **DEPLOYMENT.md** - Production deployment guide
- **EBAY_INTEGRATION.md** - eBay sales data integration
- **python-matcher/README.md** - Vector-based image matching

---

## Support

For search-related issues:
1. Check this guide first
2. Review API response for error messages
3. Check browser console for client-side errors
4. Verify database connectivity: `npx prisma studio`
5. Test API directly: `curl http://localhost:7991/api/listings?search=test`