Some checks failed
ci / ci (22, ubuntu-latest) (push) Has been cancelled
Nuxt 4 + Supabase + Flightics API. Incluye búsqueda de vuelos, inspiraciones, watchlist, tracking de precios y mapa interactivo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
import { serverSupabaseServiceRole } from '#supabase/server'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const { city } = getQuery(event)
|
|
if (!city || typeof city !== 'string') {
|
|
throw createError({ statusCode: 400, message: 'city is required' })
|
|
}
|
|
|
|
const cityKey = city.trim().toLowerCase()
|
|
const client = serverSupabaseServiceRole(event)
|
|
|
|
// Check cache first
|
|
const { data: cached } = await client
|
|
.from('destination_images')
|
|
.select('*')
|
|
.eq('city_name', cityKey)
|
|
.single()
|
|
|
|
if (cached) {
|
|
// Refresh if older than 30 days
|
|
const age = Date.now() - new Date(cached.cached_at).getTime()
|
|
if (age < 30 * 24 * 60 * 60 * 1000) {
|
|
return cached
|
|
}
|
|
}
|
|
|
|
// Fetch from Unsplash
|
|
const accessKey = process.env.UNSPLASH_ACCESS_KEY
|
|
if (!accessKey) {
|
|
throw createError({ statusCode: 500, message: 'UNSPLASH_ACCESS_KEY not configured' })
|
|
}
|
|
|
|
const result = await $fetch<{ results: { urls: { regular: string; small: string }; user: { name: string; links: { html: string } } }[] }>('https://api.unsplash.com/search/photos', {
|
|
query: {
|
|
query: `${city} city travel`,
|
|
per_page: 1,
|
|
orientation: 'landscape',
|
|
},
|
|
headers: {
|
|
Authorization: `Client-ID ${accessKey}`,
|
|
},
|
|
}).catch(() => null)
|
|
|
|
if (!result?.results?.length) {
|
|
return null
|
|
}
|
|
|
|
const photo = result.results[0]
|
|
const row = {
|
|
city_name: cityKey,
|
|
image_url: photo.urls.regular,
|
|
thumb_url: photo.urls.small,
|
|
photographer: photo.user.name,
|
|
photographer_url: photo.user.links.html,
|
|
cached_at: new Date().toISOString(),
|
|
}
|
|
|
|
// Upsert cache
|
|
await client
|
|
.from('destination_images')
|
|
.upsert(row, { onConflict: 'city_name' })
|
|
|
|
return row
|
|
})
|