diff --git a/app/api/projects/[projectId]/design-surfaces/route.ts b/app/api/projects/[projectId]/design-surfaces/route.ts index 709ce11..785e83e 100644 --- a/app/api/projects/[projectId]/design-surfaces/route.ts +++ b/app/api/projects/[projectId]/design-surfaces/route.ts @@ -3,7 +3,6 @@ import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth/authOptions'; import { query } from '@/lib/db-postgres'; - /** * GET — returns surfaces[] and surfaceThemes{} for the project. */ @@ -19,7 +18,7 @@ export async function GET( const rows = await query<{ data: Record }>( `SELECT p.data FROM fs_projects p JOIN fs_users u ON u.id = p.user_id - WHERE p.id = $1 AND u.data->>'email' = $2 + WHERE p.id = $1::text AND u.data->>'email' = $2::text LIMIT 1`, [projectId, session.user.email] ); @@ -53,14 +52,21 @@ export async function PATCH( const session = await getServerSession(authOptions); if (!session?.user?.email) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); - // Read current data (also verifies ownership) - const rows = await query<{ data: Record }>( - `SELECT p.data FROM fs_projects p - JOIN fs_users u ON u.id = p.user_id - WHERE p.id = $1 AND u.data->>'email' = $2 - LIMIT 1`, - [projectId, session.user.email] - ); + // Step 1: read current data — explicit ::text casts on every param + let rows: { data: Record }[]; + try { + rows = await query<{ data: Record }>( + `SELECT p.data FROM fs_projects p + JOIN fs_users u ON u.id = p.user_id + WHERE p.id = $1::text AND u.data->>'email' = $2::text + LIMIT 1`, + [projectId, session.user.email] + ); + } catch (selErr) { + console.error('[design-surfaces PATCH] SELECT failed:', selErr); + return NextResponse.json({ error: 'Internal error (select)' }, { status: 500 }); + } + if (rows.length === 0) return NextResponse.json({ error: 'Project not found' }, { status: 404 }); const current = rows[0].data ?? {}; @@ -83,12 +89,16 @@ export async function PATCH( return NextResponse.json({ error: 'Invalid body' }, { status: 400 }); } - // Put projectId as $1 (matches known-working pattern in other routes) - // and cast id::text to avoid "could not determine data type of parameter" (42P18) - await query( - `UPDATE fs_projects SET data = $2::jsonb WHERE id::text = $1`, - [projectId, JSON.stringify(updated)] - ); + // Step 2: write back — explicit ::text cast on id param, ::jsonb on data param + try { + await query( + `UPDATE fs_projects SET data = $1::jsonb WHERE id = $2::text`, + [JSON.stringify(updated), projectId] + ); + } catch (updErr) { + console.error('[design-surfaces PATCH] UPDATE failed:', updErr); + return NextResponse.json({ error: 'Internal error (update)' }, { status: 500 }); + } return NextResponse.json({ success: true }); } catch (err) {