From affdf1661dc354c2b94bbd315af6e0fea713b702 Mon Sep 17 00:00:00 2001 From: Hermes Date: Sun, 2 Aug 2026 02:26:36 +0000 Subject: [PATCH] fix: map Drizzle camelCase fields to frontend snake_case fields in reports API --- apps/web/app/api/reports/[id]/route.ts | 20 ++++++++++++++++++-- apps/web/app/api/reports/route.ts | 21 +++++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/apps/web/app/api/reports/[id]/route.ts b/apps/web/app/api/reports/[id]/route.ts index 3f091d7..0ce4873 100644 --- a/apps/web/app/api/reports/[id]/route.ts +++ b/apps/web/app/api/reports/[id]/route.ts @@ -4,6 +4,22 @@ import { db, reports } from '@project-e/db'; import { eq } from 'drizzle-orm'; import { z } from 'zod'; +function mapReport(report: Record) { + return { + id: report.id, + title: report.title, + content: report.content || '', + report_type: report.reportType || report.report_type || 'custom', + date_range_start: report.dateRangeStart?.toISOString?.() || report.date_range_start || null, + date_range_end: report.dateRangeEnd?.toISOString?.() || report.date_range_end || null, + domain: report.domain || 'personal', + is_draft: report.isDraft ?? report.is_draft ?? false, + created: report.createdAt?.toISOString?.() || report.created || new Date().toISOString(), + updated: report.updatedAt?.toISOString?.() || report.updated || new Date().toISOString(), + }; +} + + const updateReportSchema = z.object({ title: z.string().min(1, 'Title is required').optional(), content: z.string().optional(), @@ -29,7 +45,7 @@ export const GET = withAuth(async (request: NextRequest, _user, co return createErrorResponse('NOT_FOUND', 'Report not found', 404); } - return NextResponse.json(report); + return NextResponse.json(mapReport(report)); }); // PATCH /api/reports/[id] — Update a report @@ -58,7 +74,7 @@ export const PATCH = withAuth(async (request: NextRequest, _user, return createErrorResponse('NOT_FOUND', 'Report not found', 404); } - return NextResponse.json(report); + return NextResponse.json(mapReport(report)); } catch (error) { if (error instanceof z.ZodError) { return createErrorResponse('VALIDATION_ERROR', 'Invalid input', 400, error.issues); diff --git a/apps/web/app/api/reports/route.ts b/apps/web/app/api/reports/route.ts index 8772397..ccec540 100644 --- a/apps/web/app/api/reports/route.ts +++ b/apps/web/app/api/reports/route.ts @@ -4,6 +4,23 @@ import { db, reports } from '@project-e/db'; import { and, asc, desc, eq, ilike, or, sql } from 'drizzle-orm'; import { z } from 'zod'; +// Map Drizzle DB fields to frontend-expected field names +function mapReport(report: Record) { + return { + id: report.id, + title: report.title, + content: report.content || '', + report_type: report.reportType || report.report_type || 'custom', + date_range_start: report.dateRangeStart?.toISOString?.() || report.date_range_start || null, + date_range_end: report.dateRangeEnd?.toISOString?.() || report.date_range_end || null, + domain: report.domain || 'personal', + is_draft: report.isDraft ?? report.is_draft ?? false, + created: report.createdAt?.toISOString?.() || report.created || new Date().toISOString(), + updated: report.updatedAt?.toISOString?.() || report.updated || new Date().toISOString(), + }; +} + + const createReportSchema = z.object({ title: z.string().min(1, 'Title is required').default('Untitled report'), content: z.string().optional().default(''), @@ -60,7 +77,7 @@ export const GET = withAuth(async (request: NextRequest, _user) => { const totalItems = Number(countResult[0]?.count || 0); return NextResponse.json({ - items, + items: items.map(mapReport), totalItems, totalPages: Math.ceil(totalItems / perPage), page, @@ -85,7 +102,7 @@ export const POST = withAuth(async (request: NextRequest, _user) => { }) .returning(); - return NextResponse.json(report, { status: 201 }); + return NextResponse.json(mapReport(report), { status: 201 }); } catch (error) { if (error instanceof z.ZodError) { return createErrorResponse('VALIDATION_ERROR', 'Invalid input', 400, error.issues);