fix: resolve production UnrecognizedActionError by externalizing entity server actions into stable top-level exports
This commit is contained in:
parent
64c6568a99
commit
44947d0d29
73
src/app/actions/entities.ts
Normal file
73
src/app/actions/entities.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
'use server';
|
||||||
|
|
||||||
|
import { collectionMap, SCHEMA_MAP } from '@/lib/schema';
|
||||||
|
import { createDocumentServer, updateDocumentServer } from './appwrite';
|
||||||
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Centralized action to create a new entity document
|
||||||
|
*/
|
||||||
|
export async function saveEntityAction(entity: string, formData: FormData) {
|
||||||
|
const collectionId = collectionMap[entity];
|
||||||
|
const fields = SCHEMA_MAP[entity] || [];
|
||||||
|
|
||||||
|
if (!collectionId) throw new Error(`Colección no encontrada para ${entity}`);
|
||||||
|
|
||||||
|
const data: Record<string, any> = {};
|
||||||
|
for (const [key, value] of formData.entries()) {
|
||||||
|
if (key.startsWith('$ACTION')) continue;
|
||||||
|
data[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type conversions based on schema
|
||||||
|
const numericFields = fields.filter(f => f.type === 'number').map(f => f.name);
|
||||||
|
for (const nKey of numericFields) {
|
||||||
|
if (data[nKey]) data[nKey] = parseFloat(data[nKey]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalization
|
||||||
|
if (data.estado && typeof data.estado === 'string') {
|
||||||
|
data.estado = data.estado.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await createDocumentServer(collectionId, data);
|
||||||
|
if (res.success) {
|
||||||
|
redirect(`/dashboard/${entity}`);
|
||||||
|
} else {
|
||||||
|
throw new Error(res.error || "Error desconocido al crear documento");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Centralized action to update an existing entity document
|
||||||
|
*/
|
||||||
|
export async function updateEntityAction(entity: string, id: string, formData: FormData) {
|
||||||
|
const collectionId = collectionMap[entity];
|
||||||
|
const fields = SCHEMA_MAP[entity] || [];
|
||||||
|
|
||||||
|
if (!collectionId) throw new Error(`Colección no encontrada para ${entity}`);
|
||||||
|
|
||||||
|
const data: Record<string, any> = {};
|
||||||
|
for (const [key, value] of formData.entries()) {
|
||||||
|
if (key.startsWith('$ACTION')) continue;
|
||||||
|
data[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type conversions based on schema
|
||||||
|
const numericFields = fields.filter(f => f.type === 'number').map(f => f.name);
|
||||||
|
for (const nKey of numericFields) {
|
||||||
|
if (data[nKey]) data[nKey] = parseFloat(data[nKey]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalization
|
||||||
|
if (data.estado && typeof data.estado === 'string') {
|
||||||
|
data.estado = data.estado.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await updateDocumentServer(collectionId, id, data);
|
||||||
|
if (res.success) {
|
||||||
|
redirect(`/dashboard/${entity}`);
|
||||||
|
} else {
|
||||||
|
throw new Error(res.error || "Error desconocido al actualizar documento");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ import { APPWRITE_ALMEIRA_CONFIG, projectId, endpoint } from '@/lib/appwrite';
|
|||||||
import { createSessionClient } from '@/lib/appwrite.server';
|
import { createSessionClient } from '@/lib/appwrite.server';
|
||||||
import { collectionMap, SCHEMA_MAP } from '@/lib/schema';
|
import { collectionMap, SCHEMA_MAP } from '@/lib/schema';
|
||||||
import { updateDocumentServer } from '@/app/actions/appwrite';
|
import { updateDocumentServer } from '@/app/actions/appwrite';
|
||||||
|
import { updateEntityAction } from '@/app/actions/entities';
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
import { EntityForm } from '@/components/dashboard/EntityForm';
|
import { EntityForm } from '@/components/dashboard/EntityForm';
|
||||||
|
|
||||||
@ -58,31 +59,7 @@ export default async function EditEntityPage({ params }: { params: Promise<{ ent
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
async function updateAction(formData: FormData) {
|
const boundUpdate = updateEntityAction.bind(null, entity, id);
|
||||||
'use server';
|
|
||||||
|
|
||||||
const data: Record<string, any> = {};
|
|
||||||
for (const [key, value] of formData.entries()) {
|
|
||||||
if (key.startsWith('$ACTION')) continue;
|
|
||||||
data[key] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numericFields = fields.filter(f => f.type === 'number').map(f => f.name);
|
|
||||||
for (const nKey of numericFields) {
|
|
||||||
if(data[nKey]) data[nKey] = parseFloat(data[nKey]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.estado && typeof data.estado === 'string') {
|
|
||||||
data.estado = data.estado.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await updateDocumentServer(collectionId, id, data);
|
|
||||||
if(res.success) {
|
|
||||||
redirect(`/dashboard/${entity}`);
|
|
||||||
} else {
|
|
||||||
console.error("Server Action res error", res.error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EntityForm
|
<EntityForm
|
||||||
@ -91,7 +68,7 @@ export default async function EditEntityPage({ params }: { params: Promise<{ ent
|
|||||||
initialData={document}
|
initialData={document}
|
||||||
fields={fields}
|
fields={fields}
|
||||||
relationData={relationData}
|
relationData={relationData}
|
||||||
submitAction={updateAction}
|
submitAction={boundUpdate}
|
||||||
appwriteConfig={{ endpoint, projectId }}
|
appwriteConfig={{ endpoint, projectId }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { APPWRITE_ALMEIRA_CONFIG, projectId, endpoint } from '@/lib/appwrite';
|
|||||||
import { createSessionClient } from '@/lib/appwrite.server';
|
import { createSessionClient } from '@/lib/appwrite.server';
|
||||||
import { collectionMap, SCHEMA_MAP } from '@/lib/schema';
|
import { collectionMap, SCHEMA_MAP } from '@/lib/schema';
|
||||||
import { createDocumentServer } from '@/app/actions/appwrite';
|
import { createDocumentServer } from '@/app/actions/appwrite';
|
||||||
|
import { saveEntityAction } from '@/app/actions/entities';
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
import { EntityForm } from '@/components/dashboard/EntityForm';
|
import { EntityForm } from '@/components/dashboard/EntityForm';
|
||||||
|
|
||||||
@ -41,31 +42,7 @@ export default async function NewEntityPage({ params }: { params: Promise<{ enti
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
async function submitAction(formData: FormData) {
|
const boundSave = saveEntityAction.bind(null, entity);
|
||||||
'use server';
|
|
||||||
|
|
||||||
const data: Record<string, any> = {};
|
|
||||||
for (const [key, value] of formData.entries()) {
|
|
||||||
if (key.startsWith('$ACTION')) continue;
|
|
||||||
data[key] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numericFields = fields.filter(f => f.type === 'number').map(f => f.name);
|
|
||||||
for (const nKey of numericFields) {
|
|
||||||
if(data[nKey]) data[nKey] = parseFloat(data[nKey]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.estado && typeof data.estado === 'string') {
|
|
||||||
data.estado = data.estado.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await createDocumentServer(collectionId, data);
|
|
||||||
if(res.success) {
|
|
||||||
redirect(`/dashboard/${entity}`);
|
|
||||||
} else {
|
|
||||||
console.error("Server Action res error", res.error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EntityForm
|
<EntityForm
|
||||||
@ -73,7 +50,7 @@ export default async function NewEntityPage({ params }: { params: Promise<{ enti
|
|||||||
entityName={entityName}
|
entityName={entityName}
|
||||||
fields={fields}
|
fields={fields}
|
||||||
relationData={relationData}
|
relationData={relationData}
|
||||||
submitAction={submitAction}
|
submitAction={boundSave}
|
||||||
appwriteConfig={{ endpoint, projectId }}
|
appwriteConfig={{ endpoint, projectId }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user