feat: improve compare API route with searching stage and validation

This commit is contained in:
Christopher Mayor
2026-04-24 14:36:06 -07:00
parent 2f4239a83b
commit a273f29e07

View File

@@ -18,6 +18,10 @@ function slugify(text: string): string {
.slice(0, 200);
}
// TODO: Implement rate limiting per IP/user
// Example: Use Upstash Ratelimit or a simple in-memory counter
// const ratelimit = new Ratelimit({ redis, limiter: slidingWindow(5, "1m") })
export async function POST(request: Request) {
const body: { query?: string; items?: string[]; dimensions?: string[] } =
await request.json();
@@ -25,7 +29,21 @@ export async function POST(request: Request) {
if (!items || items.length < 2) {
return Response.json(
{ error: "At least 2 items are required" },
{ error: "At least 2 items are required for comparison" },
{ status: 400 }
);
}
if (items.length > 10) {
return Response.json(
{ error: "Maximum 10 items allowed per comparison" },
{ status: 400 }
);
}
if (items.some((item) => item.trim().length === 0)) {
return Response.json(
{ error: "Item names cannot be empty" },
{ status: 400 }
);
}
@@ -70,6 +88,20 @@ export async function POST(request: Request) {
);
}
if (progress.stage === "searching") {
controller.enqueue(
encoder.encode(
serializeSSE("progress", {
status: "researching",
message: `Searching the web for ${progress.item}... (${progress.results} results found)`,
itemsCompleted,
totalItems: items.length,
currentStep: `Searching ${progress.item}`,
})
)
);
}
if (progress.stage === "researching") {
itemsCompleted++;
controller.enqueue(
@@ -102,7 +134,17 @@ export async function POST(request: Request) {
if (progress.stage === "complete") {
const result = progress.result;
const comparisonData: Omit<ComparisonData, "id" | "userId" | "slug" | "tags" | "isPublic" | "viewCount" | "createdAt" | "updatedAt"> = {
const comparisonData: Omit<
ComparisonData,
| "id"
| "userId"
| "slug"
| "tags"
| "isPublic"
| "viewCount"
| "createdAt"
| "updatedAt"
> = {
title,
query: query || "",
status: "completed",
@@ -177,7 +219,7 @@ export async function POST(request: Request) {
encoder.encode(
serializeSSE("progress", {
status: "failed",
message: progress.error,
message: `Comparison failed: ${progress.error}`,
itemsCompleted,
totalItems: items.length,
currentStep: "Failed",
@@ -192,11 +234,16 @@ export async function POST(request: Request) {
.set({ status: "failed", updatedAt: new Date() })
.where(eq(comparisons.id, id));
const message =
error instanceof Error
? error.message
: "An unexpected error occurred during research";
controller.enqueue(
encoder.encode(
serializeSSE("progress", {
status: "failed",
message: error instanceof Error ? error.message : "Unknown error",
message: `Comparison failed: ${message}`,
itemsCompleted,
totalItems: items.length,
currentStep: "Failed",