From ec8a08c17cefa92e5cab61b2dcb5e3d5124d152e Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Tue, 17 Mar 2026 08:50:40 +0000 Subject: [PATCH 1/2] [#231] Validate plot existence before allowing comments POST /api/comments now returns 400 if the (storyline_id, plot_index) pair doesn't exist in the plots table, preventing comments on non-existent plot indexes. Fixes #231 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/api/comments/route.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/app/api/comments/route.ts b/src/app/api/comments/route.ts index cd36d19c..19a03da5 100644 --- a/src/app/api/comments/route.ts +++ b/src/app/api/comments/route.ts @@ -113,6 +113,18 @@ export async function POST(req: NextRequest) { const serverClient = createServerClient(); if (!serverClient) return error("Supabase not configured", 500); + // Validate that the (storyline_id, plot_index) pair exists + const { data: plot } = await serverClient.from("plots") + .select("id") + .eq("storyline_id", storylineId) + .eq("plot_index", plotIndex) + .eq("contract_address", STORY_FACTORY.toLowerCase()) + .limit(1); + + if (!plot || plot.length === 0) { + return error("Plot does not exist"); + } + // Rate limit: max 1 comment per address per plot per minute const oneMinuteAgo = new Date(Date.now() - 60 * 1000).toISOString(); const { data: recent } = await serverClient.from("comments") From cb99276022f0e439596320797c6482dd087096d6 Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Tue, 17 Mar 2026 08:52:11 +0000 Subject: [PATCH 2/2] [#231] Handle plot lookup DB error before empty-result check Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/api/comments/route.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/api/comments/route.ts b/src/app/api/comments/route.ts index 19a03da5..ebafa15a 100644 --- a/src/app/api/comments/route.ts +++ b/src/app/api/comments/route.ts @@ -114,13 +114,14 @@ export async function POST(req: NextRequest) { if (!serverClient) return error("Supabase not configured", 500); // Validate that the (storyline_id, plot_index) pair exists - const { data: plot } = await serverClient.from("plots") + const { data: plot, error: plotError } = await serverClient.from("plots") .select("id") .eq("storyline_id", storylineId) .eq("plot_index", plotIndex) .eq("contract_address", STORY_FACTORY.toLowerCase()) .limit(1); + if (plotError) return error(`Database error: ${plotError.message}`, 500); if (!plot || plot.length === 0) { return error("Plot does not exist"); }