From b58a2a59fbe153360a808ef09a17cae75ba84259 Mon Sep 17 00:00:00 2001 From: "Carlos (Almeira)" Date: Sat, 28 Mar 2026 12:05:41 -0500 Subject: [PATCH] fix: resolve 'Only plain objects' serialization errors across dashboard and home - Applied JSON.parse(JSON.stringify()) sanitization to documents and relationData in EditEntityPage. - Sanitized relationData and user in NewEntityPage. - Sanitized posts and settings in Homepage. - Added missing Query import to dashboard edit page. - This ensures all data passed to Client Components is in a serializable POJO format. --- src/app/dashboard/[entity]/[id]/page.tsx | 11 ++++++----- src/app/dashboard/[entity]/new/page.tsx | 4 ++-- src/app/page.tsx | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/app/dashboard/[entity]/[id]/page.tsx b/src/app/dashboard/[entity]/[id]/page.tsx index d199394..499c7a0 100644 --- a/src/app/dashboard/[entity]/[id]/page.tsx +++ b/src/app/dashboard/[entity]/[id]/page.tsx @@ -1,5 +1,6 @@ import { APPWRITE_ALMEIRA_CONFIG, projectId, endpoint } from '@/lib/appwrite'; import { createSessionClient, getLoggedInUser } from '@/lib/appwrite.server'; +import { Query } from 'node-appwrite'; import { collectionMap, SCHEMA_MAP } from '@/lib/schema'; import { updateDocumentServer } from '@/app/actions/appwrite'; import { updateEntityAction } from '@/app/actions/entities'; @@ -27,7 +28,7 @@ export default async function EditEntityPage({ params }: { params: Promise<{ ent } const sessionClient = await createSessionClient(); - const user = await getLoggedInUser(); + const user = JSON.parse(JSON.stringify(await getLoggedInUser())); if (!sessionClient || !user) { redirect('/login'); } @@ -35,11 +36,11 @@ export default async function EditEntityPage({ params }: { params: Promise<{ ent // Fetch the existing document let document: any = null; try { - document = await sessionClient.databases.getDocument( + document = JSON.parse(JSON.stringify(await sessionClient.databases.getDocument( APPWRITE_ALMEIRA_CONFIG.databaseId, collectionId, id - ); + ))); } catch (e) { return (
@@ -55,8 +56,8 @@ export default async function EditEntityPage({ params }: { params: Promise<{ ent try { const relKey = field.relationCollection as string; if(!collectionMap[relKey]) return; - const res = await sessionClient.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, collectionMap[relKey], []); - relationData[field.name] = res.documents; + const res = await sessionClient.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, collectionMap[relKey], [Query.limit(100)]); + relationData[field.name] = JSON.parse(JSON.stringify(res.documents)); } catch(e) { console.error('Error obteniendo relaciones de', field.name, e); } }) ); diff --git a/src/app/dashboard/[entity]/new/page.tsx b/src/app/dashboard/[entity]/new/page.tsx index 69a25ea..7d24374 100644 --- a/src/app/dashboard/[entity]/new/page.tsx +++ b/src/app/dashboard/[entity]/new/page.tsx @@ -29,7 +29,7 @@ export default async function NewEntityPage({ } // Auth check - const user = await getLoggedInUser(); + const user = JSON.parse(JSON.stringify(await getLoggedInUser())); if (!user) redirect('/login'); // Pre-load all relation data server-side @@ -49,7 +49,7 @@ export default async function NewEntityPage({ relColId, [Query.limit(100)] ); - relationData[field.name] = res.documents as Array<{ $id: string; [key: string]: unknown }>; + relationData[field.name] = JSON.parse(JSON.stringify(res.documents)); } catch { // Silent fail for individual relations } diff --git a/src/app/page.tsx b/src/app/page.tsx index 3196a58..b5acb67 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -15,12 +15,12 @@ async function fetchHomeData() { // 1. Settings const settingsRes = await client.databases.listDocuments(APPWRITE_ALMEIRA_CONFIG.databaseId, 'settings', []); - const settings = (settingsRes.documents.length > 0 ? settingsRes.documents[0] : { + const settings = JSON.parse(JSON.stringify(settingsRes.documents.length > 0 ? settingsRes.documents[0] : { ticker_count: 10, rotation_seconds: 5, feed_news_count: 12, show_news_date: true - }) as Settings; + })) as Settings; const postsCount = settings.feed_news_count || 12; const cardSettings = { @@ -55,10 +55,10 @@ async function fetchHomeData() { Query.equal('$id', mediaIds) ]); const mediaMap = new Map(mediaRes.documents.map(m => [m.$id, m as unknown as MediaItem])); - posts = posts.map(p => ({ + posts = posts.map(p => JSON.parse(JSON.stringify({ ...p, resolved_media: mediaMap.get(p.imagen_destacada_id as string) - })); + }))); } }