import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { convexAuthNextjsToken, isAuthenticatedNextjs } from "@convex-dev/auth/nextjs/server"; import { fetchMutation, fetchQuery } from "convex/nextjs"; import { api } from "@/convex/_generated/api"; import { scrapeWebsite, analyzeFromText } from "@/lib/scraper"; import { repromptSection } from "@/lib/analysis-pipeline"; const bodySchema = z.object({ analysisId: z.string().min(1), sectionKey: z.enum([ "profile", "features", "competitors", "keywords", "problems", "personas", "useCases", "dorkQueries", ]), prompt: z.string().optional(), }); export async function POST(request: NextRequest) { if (!(await isAuthenticatedNextjs())) { const redirectUrl = new URL("/auth", request.url); const referer = request.headers.get("referer"); const nextPath = referer ? new URL(referer).pathname + new URL(referer).search : "/"; redirectUrl.searchParams.set("next", nextPath); return NextResponse.redirect(redirectUrl); } const body = await request.json(); const parsed = bodySchema.parse(body); const token = await convexAuthNextjsToken(); const analysis = await fetchQuery( api.analyses.getById, { analysisId: parsed.analysisId as any }, { token } ); if (!analysis) { return NextResponse.json({ error: "Analysis not found." }, { status: 404 }); } const dataSource = await fetchQuery( api.dataSources.getById, { dataSourceId: analysis.dataSourceId as any }, { token } ); if (!dataSource) { return NextResponse.json({ error: "Data source not found." }, { status: 404 }); } const isManual = dataSource.url.startsWith("manual:") || dataSource.url === "manual-input"; const featureText = (analysis.features || []).map((f: any) => f.name).join("\n"); const content = isManual ? await analyzeFromText( analysis.productName, analysis.description || "", featureText ) : await scrapeWebsite(dataSource.url); const items = await repromptSection( parsed.sectionKey, content, analysis as any, parsed.prompt ); await fetchMutation( api.analysisSections.replaceSection, { analysisId: parsed.analysisId as any, sectionKey: parsed.sectionKey, items, lastPrompt: parsed.prompt, source: "ai", }, { token } ); return NextResponse.json({ success: true, items }); }