Files
twenty/packages/twenty-docs/l/es/developers/extend/apps/config/install-hooks.mdx
T
github-actions[bot] ebee7d71b9 i18n - docs translations (#22715)
Created by Github action

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22715?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Co-authored-by: github-actions <github-actions@twenty.com>
2026-07-09 11:51:54 +02:00

145 lines
11 KiB
Plaintext

---
title: Hooks de instalación
description: "Ejecuta lógica antes o después de la instalación: introduce datos iniciales, haz copias de seguridad de los registros, valida la actualización."
icon: wrench
---
Los hooks de instalación son funciones de lógica especiales que se ejecutan durante el ciclo de vida de la instalación o actualización. Comparten el mismo tiempo de ejecución del handler que las [logic functions](/l/es/developers/extend/apps/logic/logic-functions) normales y reciben un `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` es `undefined` en una instalación nueva), pero se declaran con sus propias funciones define y viven fuera del modelo de disparadores normal (HTTP, cron, eventos de base de datos).
Cada aplicación puede definir **como máximo una función de preinstalación** y **como máximo una función de posinstalación**. La compilación del manifiesto genera un error si se detecta más de una de cualquiera de las dos.
```
┌─────────────────────────────────────────────────────────────┐
│ install flow │
│ │
│ upload package → [pre-install] → metadata migration → │
│ generate SDK → [post-install] │
│ │
│ old schema visible new schema visible │
└─────────────────────────────────────────────────────────────┘
```
## De un vistazo
| | `definePreInstallLogicFunction` | `definePostInstallLogicFunction` |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ejecuciones | Antes de la migración de metadatos — el esquema y los datos **anteriores** siguen intactos | Después de la migración y la generación del SDK — el esquema **nuevo** está en su lugar |
| Ejecución | Siempre síncrona; bloquea la instalación | Asíncrona de forma predeterminada (en cola, 3 reintentos); modo síncrono opcional mediante `shouldRunSynchronously: true` |
| En caso de fallo | La instalación se **aborta** antes de cualquier cambio de esquema | Asíncrono: se vuelve a intentar hasta 3 veces. Síncrono: quien realiza la llamada recibe `POST_INSTALL_ERROR` (los cambios de esquema **no** se revierten) |
| Uso típico | Hacer copia de seguridad o corregir datos que una migración perdería; rechazar una actualización arriesgada lanzando una excepción | Sembrar datos predeterminados, configurar el espacio de trabajo, registrar recursos externos |
**Regla general:** usa post-install de forma predeterminada. Recurra a la pre-instalación solo cuando la propia migración sea destructiva y necesite interceptar el estado anterior antes de que desaparezca.
| Quiere... | Usar |
| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| Sembrar datos, configurar el espacio de trabajo, registrar recursos externos | `post-install` |
| Trabajo de larga duración que no debería bloquear la respuesta de instalación | `post-install` (modo asíncrono predeterminado, con reintentos del worker) |
| Configuración rápida de la que el cliente depende inmediatamente después de que finaliza la instalación | `post-install` con `shouldRunSynchronously: true` |
| Leer o hacer copia de seguridad de datos que la próxima migración perdería | `pre-install` |
| Rechazar una actualización que corrompería datos existentes | `pre-install` (lanzar desde el controlador) |
| Reconciliación en cada actualización | Cualquiera de los hooks con `shouldRunOnVersionUpgrade: true` |
## Comportamiento compartido por ambos hooks
* La configuración es una configuración de `defineLogicFunction` menos los ajustes de disparador, más `shouldRunOnVersionUpgrade`.
* **Cuándo se ejecuta**: solo en instalaciones nuevas, de forma predeterminada. Configura `shouldRunOnVersionUpgrade: true` para que también se ejecute en las actualizaciones. Usa `previousVersion` / `newVersion` para ramificar según la ruta de actualización.
* **La idempotencia es importante**: el post-install asíncrono puede reintentarse y cualquiera de los hooks se vuelve a ejecutar en las actualizaciones cuando `shouldRunOnVersionUpgrade` está activado.
* El entorno habitual de las logic functions (`APPLICATION_ID`, `APP_ACCESS_TOKEN`, `API_URL`) se inyecta, por lo que puedes llamar a la API de Twenty con el token de tu app.
* El hook se adjunta automáticamente al manifiesto de la aplicación en tiempo de compilación (`preInstallLogicFunction` / `postInstallLogicFunction`) — no hay nada que referenciar en [`defineApplication()`](/l/es/developers/extend/apps/config/application).
* El `timeoutSeconds` predeterminado es 300 para permitir tareas de configuración más largas como la siembra de datos.
* **No se ejecuta en modo de desarrollo**: `yarn twenty dev` omite el flujo de instalación y sincroniza los archivos directamente, por lo que los hooks nunca se ejecutan ahí. En su lugar, dispáralos manualmente:
```bash filename="Terminal"
yarn twenty dev:function:exec --postInstall
yarn twenty dev:function:exec --preInstall
```
<AccordionGroup>
<Accordion title="definePostInstallLogicFunction" description="Se ejecuta después de que se aplique la migración de metadatos del espacio de trabajo">
Se ejecuta una vez que tu app ha terminado de instalarse: metadatos sincronizados, cliente SDK generado, nuevo esquema disponible para consulta. Ejemplo — sembrar un registro predeterminado en instalaciones nuevas:
```ts src/logic-functions/post-install.ts
import { definePostInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
import { CoreApiClient } from 'twenty-client-sdk/core';
const handler = async ({ previousVersion }: InstallPayload): Promise<void> => {
if (previousVersion) return; // fresh installs only
const client = new CoreApiClient();
await client.mutation({
createPostCard: {
__args: { data: { name: 'Welcome to Postcard', content: 'Your first card!' } },
id: true,
},
});
};
export default definePostInstallLogicFunction({
universalIdentifier: 'f7a2b9c1-3d4e-5678-abcd-ef9876543210',
name: 'post-install',
description: 'Seeds a welcome post card after install.',
timeoutSeconds: 300,
shouldRunOnVersionUpgrade: false,
shouldRunSynchronously: false,
handler,
});
```
El flag `shouldRunSynchronously` controla el modelo de ejecución:
* `false` *(predeterminado)* — encolado en la cola de mensajes (`retryLimit: 3`) y ejecutado por un worker. La respuesta de instalación se devuelve tan pronto como el trabajo se pone en la cola. **Usar para trabajo de larga duración** — siembra de grandes conjuntos de datos, APIs de terceros lentas.
* `true` — se ejecuta en línea durante el flujo de instalación. La solicitud de instalación se bloquea hasta que el handler finaliza; un error lanzado aparece como `POST_INSTALL_ERROR` para quien realiza la llamada (sin reintentos). **Usar para trabajo rápido que debe completarse antes de la respuesta.** La migración ya se ha aplicado en este punto, por lo que un fallo no revierte los cambios de esquema — solo expone el error.
</Accordion>
<Accordion title="definePreInstallLogicFunction" description="Se ejecuta antes de que se aplique la migración de metadatos del espacio de trabajo">
Se ejecuta antes de la migración de metadatos, contra el esquema **anterior** — el lugar adecuado para hacer una copia de seguridad de los datos que una migración perdería o para rechazar una actualización arriesgada. Antes de ejecutarse, el servidor realiza una "sincronización simplificada" puramente aditiva que registra solo la función de pre-instalación de la versión nueva; todo lo demás — los objetos, campos y datos de la versión anterior — permanece sin cambios cuando se ejecuta tu handler.
La pre-instalación siempre es **síncrona** y bloquea la instalación. Si el handler lanza una excepción, la instalación se aborta antes de cualquier cambio de esquema — el espacio de trabajo permanece en la versión anterior en un estado consistente. Esto es intencional: la pre-instalación es su última oportunidad para rechazar una actualización arriesgada.
Ejemplo — copiar los valores de un campo heredado antes de que la migración lo elimine:
```ts src/logic-functions/pre-install.ts
import { definePreInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
import { CoreApiClient } from 'twenty-client-sdk/core';
const handler = async ({ previousVersion, newVersion }: InstallPayload): Promise<void> => {
// Only the 1.x → 2.x upgrade drops the legacy `notes` field.
if (!previousVersion?.startsWith('1.') || !newVersion.startsWith('2.')) {
return;
}
const client = new CoreApiClient();
const { postCards } = await client.query({
postCards: {
__args: { filter: { notes: { isNot: null } } },
edges: { node: { id: true, notes: true } },
},
});
// Copy legacy `notes` into `description` before the migration drops the
// column. If this fails, the upgrade aborts and the workspace stays on v1.
for (const { node } of postCards.edges) {
await client.mutation({
updatePostCard: {
__args: { id: node.id, data: { description: node.notes } },
id: true,
},
});
}
};
export default definePreInstallLogicFunction({
universalIdentifier: 'a1b2c3d4-5678-90ab-cdef-1234567890ab',
name: 'pre-install',
description: 'Backs up legacy notes into description before the v2 migration.',
timeoutSeconds: 300,
shouldRunOnVersionUpgrade: true,
handler,
});
```
</Accordion>
</AccordionGroup>