Files
2026-02-04 01:05:00 +00:00

88 lines
2.4 KiB
TypeScript

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 });
}