import { NextResponse } from 'next/server'; import { getPayload } from 'payload'; import configPromise from '../../../payload.config'; import { upsertProductVector } from '../../../src/lib/qdrant'; export const dynamic = 'force-dynamic'; export const maxDuration = 120; /** * Internal endpoint called by the warmup script on every dev boot. * Syncs posts, pages, and products from Payload CMS into Qdrant. * NOT for form entries, media, or users. */ export async function GET() { const results = { products: 0, posts: 0, pages: 0, errors: [] as string[] }; try { const payload = await getPayload({ config: configPromise }); // ── Products ── const { docs: products } = await payload.find({ collection: 'products', limit: 1000, depth: 0, where: { _status: { equals: 'published' } }, }); for (const product of products) { try { const contentText = `${product.title} - SKU: ${product.sku}\n${product.description || ''}`; await upsertProductVector(String(product.id), contentText, { type: 'product', data: { title: product.title, sku: product.sku, slug: product.slug, description: product.description, }, }); results.products++; } catch (e: any) { results.errors.push(`product:${product.sku}: ${e.message}`); } } // ── Posts ── const { docs: posts } = await payload.find({ collection: 'posts', limit: 1000, depth: 0, where: { _status: { equals: 'published' } }, }); for (const post of posts) { try { const contentText = [ `Blog-Artikel: ${post.title}`, post.excerpt ? `Zusammenfassung: ${post.excerpt}` : '', post.category ? `Kategorie: ${post.category}` : '', ] .filter(Boolean) .join('\n'); await upsertProductVector(`post_${post.id}`, contentText, { type: 'knowledge', content: contentText, data: { title: post.title, slug: post.slug, }, }); results.posts++; } catch (e: any) { results.errors.push(`post:${post.slug}: ${e.message}`); } } // ── Pages ── const { docs: pages } = await payload.find({ collection: 'pages', limit: 1000, depth: 0, where: { _status: { equals: 'published' } }, }); for (const page of pages) { try { const contentText = [ `Seite: ${page.title}`, page.excerpt ? `Beschreibung: ${page.excerpt}` : '', ] .filter(Boolean) .join('\n'); await upsertProductVector(`page_${page.id}`, contentText, { type: 'knowledge', content: contentText, data: { title: page.title, slug: page.slug, }, }); results.pages++; } catch (e: any) { results.errors.push(`page:${page.slug}: ${e.message}`); } } console.log( `[Qdrant Sync] ✅ ${results.products} products, ${results.posts} posts, ${results.pages} pages synced`, ); return NextResponse.json({ success: true, synced: { products: results.products, posts: results.posts, pages: results.pages, }, errors: results.errors.length > 0 ? results.errors : undefined, }); } catch (error: any) { console.error('[Qdrant Sync] ❌ Fatal error:', error); return NextResponse.json({ error: error.message }, { status: 500 }); } }