← back to Wine Finder Next
app/api/search/route.ts
73 lines
import { NextRequest, NextResponse } from 'next/server'
const wineAggregator = require('@/lib/services/wineAggregator')
const googleSheets = require('@/lib/services/googleSheets')
const slackNotifier = require('@/lib/services/slackNotifier')
export async function GET(request: NextRequest) {
try {
const searchParams = request.nextUrl.searchParams
const query = searchParams.get('q')
const sources = searchParams.get('sources')?.split(',') || ['vivino', 'totalwine', 'kl']
if (!query) {
return NextResponse.json({ error: 'Search query is required' }, { status: 400 })
}
// Search all sources in parallel
const result = await wineAggregator.searchAll(query, {
sources,
deduplicate: true,
sortBy: 'price'
})
// Log to Google Sheets (async, non-blocking)
if (result.wines && result.wines.length > 0) {
googleSheets.logMultipleWines(result.wines, query).catch((err: Error) => {
console.error('Failed to log to sheets:', err.message)
})
// Check for price spikes
const alerts = await detectPriceSpikes(result.wines)
if (alerts.length > 0) {
slackNotifier.sendAlerts(alerts).catch((err: Error) => {
console.error('Failed to send alerts:', err.message)
})
}
}
return NextResponse.json({
wines: result.wines,
total: result.wines.length,
query,
sources: result.sources
})
} catch (error: any) {
console.error('Search error:', error)
return NextResponse.json(
{ error: 'Failed to search wines', message: error.message },
{ status: 500 }
)
}
}
async function detectPriceSpikes(wines: any[]) {
const alerts: any[] = []
const threshold = parseFloat(process.env.PRICE_SPIKE_THRESHOLD || '20')
// This is a simplified version - in production, fetch historical prices from sheets
for (const wine of wines) {
// Placeholder logic - replace with actual historical price comparison
const currentPrice = parseFloat(wine.price)
if (currentPrice > 500) { // Example: alert on expensive wines
alerts.push({
wine: wine.name,
currentPrice,
message: `High-value wine detected: $${currentPrice}`
})
}
}
return alerts
}