i18n - docs translations (#23250)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
committed by
GitHub
parent
fdb8865933
commit
a3a6a55051
@@ -9,7 +9,7 @@ icon: rocket
|
||||
* **الهوية** — المعرّف الشامل، واسم العرض، والوصف.
|
||||
* **الأذونات** — الدور الذي تعمل بموجبه دوال المنطق والمكوّنات الأمامية الخاصة به.
|
||||
* **المتغيرات** *(اختياري)* — أزواج مفتاح–قيمة تُتاح لكودك كمتغيرات بيئة.
|
||||
* **خطافات ما قبل التثبيت/ما بعد التثبيت** *(اختياري)* — راجع [Logic Functions](/l/ar/developers/extend/apps/logic/logic-functions).
|
||||
* **خطافات ما قبل التثبيت/ما بعد التثبيت/إلغاء التثبيت** *(اختياري)* — راجع [Logic Functions](/l/ar/developers/extend/apps/logic/logic-functions).
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ export default defineApplication({
|
||||
* حقول `universalIdentifier` هي معرّفات حتمية تملكها أنت. أنشِئها مرة واحدة واحتفظ بها ثابتة عبر عمليات المزامنة.
|
||||
* `applicationVariables` تصبح متغيرات بيئة لوظائفك ومكوّناتك الأمامية. في وظائف المنطق (على جانب الخادم)، تكون متاحة على شكل `process.env.VARIABLE_NAME`. في المكوّنات الأمامية، استخدم `getApplicationVariable('VARIABLE_NAME')` من `twenty-sdk/front-component`. يتم حقن المتغيّرات المعلَّمة بـ `isSecret: true` في وظائف المنطق فقط. المكوّنات الأمامية تتلقّى المتغيّرات غير السرّية فقط.
|
||||
* يتم اكتشاف الدور الافتراضي تلقائيًا من ملف الدور المميز بـ [`defineApplicationRole()`](/l/ar/developers/extend/apps/config/roles) — لست بحاجة إلى الإشارة إليه من `defineApplication()`.
|
||||
* يتم اكتشاف دوال ما قبل التثبيت وما بعده تلقائيًا أثناء بناء البيان — لا حاجة للإشارة إليها في `defineApplication()`.
|
||||
* يتم اكتشاف دوال ما قبل التثبيت وما بعد التثبيت وإلغاء التثبيت تلقائيًا أثناء بناء البيان — لا حاجة للإشارة إليها في `defineApplication()`.
|
||||
* لا يزال تمرير `defaultRoleUniversalIdentifier` بشكل صريح مدعومًا من أجل التوافق مع الإصدارات السابقة، ولكنه مُهمل لصالح `defineApplicationRole()`.
|
||||
* `serverVariables` هي تكوينات وأسرار بنطاق المثيل (مثل مفاتيح واجهة برمجة التطبيقات). على عكس `applicationVariables`، فهي لا تصرح عن أي قيمة في ملف manifest — حيث يقوم مشغّل مساحة العمل بملئها من إعدادات التطبيق، ويتم حقنها في دوال المنطق فقط بعد تعيينها.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: خطافات التثبيت
|
||||
description: شغّل منطقًا قبل التثبيت أو بعده — لتهيئة البيانات، أو نسخ السجلات احتياطيًا، أو التحقّق من صحة الترقية.
|
||||
description: تشغيل المنطق أثناء دورة حياة التثبيت أو الترقية أو إلغاء التثبيت — مثل تعبئة البيانات الأوّلية، ونسخ السجلات احتياطيًا، والتحقق من الترقية، وتنظيف الموارد الخارجية.
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
خطافات التثبيت هي دوال منطقية خاصة تعمل أثناء دورة حياة التثبيت أو الترقية. تشارك نفس وقت تشغيل المعالج مثل [دوال المنطق](/l/ar/developers/extend/apps/logic/logic-functions) العادية وتتلقى `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — تكون `previousVersion` بقيمة `undefined` في التثبيت الجديد)، ولكن يتم التصريح عنها بدوال تعريف خاصة بها وتعمل خارج نموذج المشغّل المعتاد (HTTP، وcron، وأحداث قاعدة البيانات).
|
||||
خطافات التثبيت هي دوال منطقية خاصة تعمل أثناء دورة حياة التثبيت أو الترقية أو إلغاء التثبيت. تستخدم نفس وقت تشغيل المعالج مثل [دوال المنطق](/l/ar/developers/extend/apps/logic/logic-functions) العادية، ولكن يتم التصريح عنها بدوال تعريف خاصة بها وتعمل خارج نموذج المشغّل المعتاد (HTTP، وcron، وأحداث قاعدة البيانات). تتلقى خطافات التثبيت `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — تكون قيمة `previousVersion` هي `undefined` في حالة التثبيت الجديد)، بينما يتلقى خطاف إلغاء التثبيت `UninstallPayload` (`{ version?: string }` — الإصدار الذي تتم إزالته).
|
||||
|
||||
يمكن لكل تطبيق تعريف دالة واحدة على الأكثر لما قبل التثبيت ودالة واحدة على الأكثر لما بعد التثبيت. سيُنتِج إنشاء ملف البيان خطأً إذا تم اكتشاف أكثر من واحدة من أيٍّ منهما.
|
||||
يمكن لكل تطبيق تعريف **خطاف واحد كحد أقصى** من كل نوع (قبل التثبيت، بعد التثبيت، إلغاء التثبيت). سيُنتِج إنشاء ملف البيان خطأً إذا تم اكتشاف أكثر من خطاف واحد من أي نوع.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## خطاف إلغاء التثبيت
|
||||
|
||||
تُصرّح `defineUninstallLogicFunction` عن خطاف يتم تشغيله عندما يلغي المستخدم تثبيت تطبيقك. يتم تنفيذه **قبل** إزالة بيانات التعريف للتطبيق وبياناته وكوده — بمجرد تشغيل ترحيل الحذف، لن يتبقى أي شيء للتنفيذ — لذلك لا يزال بإمكان معالجك الاستعلام عن كائنات التطبيق وسجلاته. استخدمه لتنظيف الموارد الخارجية: إلغاء توفير موارد واجهة برمجة التطبيقات (API)، وحذف الروبوتات المتبقية، وإبطال الـ webhooks.
|
||||
|
||||
الملاحظات:
|
||||
|
||||
* الخطاف يعتمد على مبدأ "أقصى جهد ممكن": يتم تشغيله بشكل متزامن، ولكن في حالة الفشل يتم تسجيل الخطأ و**لا يعرقل عملية إلغاء التثبيت مطلقًا** — يجب ألا يجعل التنظيف إزالة التطبيق مستحيلة.
|
||||
* يتلقى `UninstallPayload` (`{ version?: string }` — الإصدار الذي تتم إزالته).
|
||||
* لا يتم تشغيله عند التراجع عن عملية تثبيت جديدة فاشلة — حيث لم يكتمل تثبيت التطبيق مطلقًا.
|
||||
* لا يمكن للخطاف أن يعمل بعد إزالة التطبيق، لذلك يجب أن يتم هنا أي تنظيف خارجي يعتمد على بيانات التطبيق (مثلًا: معرّفات الروبوتات المخزنة في السجلات)، وليس في مهمة مجدولة خارجية.
|
||||
* ومثل خطافات التثبيت، **لا يتم تنفيذه في وضع التطوير (dev mode)** — بدلًا من ذلك، قم بتشغيله يدويًا:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ icon: screwdriver-wrench
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ icon: screwdriver-wrench
|
||||
`defineRole` — حدِّد ما يمكن لوظائف منطق التطبيق قراءته وكتابته.
|
||||
</Card>
|
||||
<Card title="خطافات التثبيت" icon="wrench" href="/l/ar/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` و`definePostInstallLogicFunction` — نسخ البيانات احتياطيًا، تهيئة القيم الافتراضية، والتحقق من صحة الترقيات.
|
||||
`definePreInstallLogicFunction` و`definePostInstallLogicFunction` و`defineUninstallLogicFunction` — نسخ البيانات احتياطيًا، تهيئة القيم الافتراضية، التحقق من صحة الترقيات، وتنظيف الموارد عند الإزالة.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ icon: screwdriver-wrench
|
||||
|
||||
* **التطبيق (Application)** هو نقطة الدخول. يحتوي كل تطبيق على استدعاء واحد فقط `defineApplication()`، ويشير إلى **دور (Role)** واحد باعتباره الدور الافتراضي له.
|
||||
* يتحكم **الدور** في ما يمكن لوظائف منطق التطبيق ومكوّنات الواجهة الأمامية قراءته وكتابته. اتبع مبدأ أقل امتياز ممكن: امنح فقط الصلاحيات التي يحتاجها الكود فعليًا.
|
||||
* تعمل **خطافات التثبيت** أثناء التثبيت أو الترقية — ما قبل التثبيت قبل ترحيل البيانات الوصفية (كي تتمكن من رفض ترقية محفوفة بالمخاطر)، وما بعد التثبيت بعد الترحيل (كي تتمكن من تهيئة بيانات افتراضية وفق المخطط الجديد).
|
||||
* تعمل **خطافات التثبيت** أثناء التثبيت أو الترقية — ما قبل التثبيت قبل ترحيل البيانات الوصفية (كي تتمكن من رفض ترقية محفوفة بالمخاطر)، وما بعد التثبيت بعد الترحيل (كي تتمكن من تهيئة بيانات افتراضية وفق المخطط الجديد). يعمل خطاف إزالة التثبيت مباشرة قبل إزالة التطبيق، بحيث يمكنه تنظيف الموارد الخارجية بينما تظل بيانات التطبيق قابلة للقراءة.
|
||||
|
||||
<Note>
|
||||
تشارك خطافات التثبيت وقت تشغيل [وظيفة المنطق](/l/ar/developers/extend/apps/logic/logic-functions) — نفس توقيع المعالج (handler signature)، ونفس متغيرات البيئة، ونفس عميل واجهة برمجة التطبيقات (typed API client) — لكنها تُصرّح باستخدام دوال تعريف خاصة بها وتوجد خارج نموذج المشغلات العادي (HTTP، و cron، وأحداث قاعدة البيانات).
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — يراقب ملفات المصدر لديك ويزامن التغييرات مباشرةً إلى خادم Twenty متصل. يُعاد توليد عميل API مضبوط الأنواع تلقائيًا عند تغيّر المخطط.
|
||||
* **`yarn twenty dev:build`** — يجمّع TypeScript، ويضمّن الدوال المنطقية والمكوّنات الأمامية باستخدام esbuild، وينتج ملف بيان.
|
||||
* **خطّافات ما قبل/ما بعد التثبيت** — دوال اختيارية تعمل أثناء التثبيت. راجع [خطّافات التثبيت](/l/ar/developers/extend/apps/config/install-hooks) للتفاصيل.
|
||||
* **خطّافات ما قبل/ما بعد التثبيت وإلغاء التثبيت** — دوال اختيارية تعمل أثناء التثبيت أو مباشرة قبل الإزالة. راجع [خطّافات التثبيت](/l/ar/developers/extend/apps/config/install-hooks) للتفاصيل.
|
||||
|
||||
## الخطوات التالية
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="التهيئة" icon="screwdriver-wrench" href="/l/ar/developers/extend/apps/config/overview">
|
||||
هوية التطبيق، الدور الافتراضي، وخطّافات التثبيت.
|
||||
هوية التطبيق، الدور الافتراضي، وخطّافات التثبيت وإلغاء التثبيت.
|
||||
</Card>
|
||||
<Card title="بيانات" icon="database" href="/l/ar/developers/extend/apps/data/overview">
|
||||
الكائنات، الحقول، والعلاقات ثنائية الاتجاه.
|
||||
|
||||
@@ -149,7 +149,7 @@ yarn twenty apply # show the plan, then apply it
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="التهيئة" icon="screwdriver-wrench" href="/l/ar/developers/extend/apps/config/overview">
|
||||
هوية التطبيق، الدور الافتراضي، وخطّافات التثبيت، والأصول العامة.
|
||||
هوية التطبيق، الدور الافتراضي، خطّافات التثبيت وإلغاء التثبيت، والأصول العامة.
|
||||
</Card>
|
||||
<Card title="بيانات" icon="database" href="/l/ar/developers/extend/apps/data/overview">
|
||||
الكائنات، الحقول، والعلاقات ثنائية الاتجاه.
|
||||
|
||||
@@ -612,7 +612,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**خطافات التثبيت** — معالجات ما قبل التثبيت وما بعد التثبيت — تشترك في وقت التشغيل نفسه، ولكن يُصرَّح عنها بدوال تعريف خاصة بها ولا تأخذ إعدادات المشغّلات. راجع [خطافات التثبيت (Install Hooks)](/l/ar/developers/extend/apps/config/install-hooks) لمعرفة `definePreInstallLogicFunction` و `definePostInstallLogicFunction`.
|
||||
**خطافات التثبيت** — معالجات ما قبل التثبيت وما بعد التثبيت وإلغاء التثبيت — تشترك في وقت التشغيل نفسه، ولكن يُصرَّح عنها بدوال تعريف خاصة بها ولا تأخذ إعدادات المشغّلات. راجع [خطافات التثبيت (Install Hooks)](/l/ar/developers/extend/apps/config/install-hooks) لمعرفة `definePreInstallLogicFunction` و `definePostInstallLogicFunction` و `defineUninstallLogicFunction`.
|
||||
</Note>
|
||||
|
||||
## عملاء واجهة برمجة تطبيقات مضبوطة الأنواع (`twenty-client-sdk`)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## عرض سجلات الدوال (`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ Každá aplikace musí mít právě jedno volání `defineApplication`. Deklaruj
|
||||
* **Identita** — univerzální identifikátor, zobrazovaný název, popis.
|
||||
* **Oprávnění** — pod jakou rolí běží její logické funkce a frontendové komponenty.
|
||||
* **Proměnné** *(volitelné)* — páry klíč–hodnota zpřístupněné vašemu kódu jako proměnné prostředí.
|
||||
* **Předinstalační / postinstalační hooky** *(volitelné)* — viz [Logické funkce](/l/cs/developers/extend/apps/logic/logic-functions).
|
||||
* **Předinstalační / postinstalační / odinstalační hooky** *(volitelné)* — viz [Logické funkce](/l/cs/developers/extend/apps/logic/logic-functions).
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ Poznámky:
|
||||
* Pole `universalIdentifier` jsou deterministické identifikátory, které vlastníte. Vygenerujte je jednou a zachovejte je stabilní napříč synchronizacemi.
|
||||
* `applicationVariables` se stanou proměnnými prostředí pro vaše funkce a frontendové komponenty. V logických funkcích (na straně serveru) jsou dostupné jako `process.env.VARIABLE_NAME`. Ve frontendových komponentách použijte `getApplicationVariable('VARIABLE_NAME')` z `twenty-sdk/front-component`. Proměnné označené jako `isSecret: true` jsou předávány pouze do logických funkcí. Frontendové komponenty přijímají pouze proměnné, které nejsou tajné.
|
||||
* Výchozí role je automaticky detekována ze souboru role označeného pomocí [`defineApplicationRole()`](/l/cs/developers/extend/apps/config/roles) — není potřeba na ni odkazovat z `defineApplication()`.
|
||||
* Předinstalační a postinstalační funkce jsou při sestavení manifestu detekovány automaticky — není třeba na ně odkazovat v `defineApplication()`.
|
||||
* Předinstalační, postinstalační a odinstalační funkce jsou při sestavení manifestu detekovány automaticky — není třeba na ně odkazovat v `defineApplication()`.
|
||||
* Předávání `defaultRoleUniversalIdentifier` explicitně je stále podporováno kvůli zpětné kompatibilitě, ale je zastaralé ve prospěch `defineApplicationRole()`.
|
||||
* `serverVariables` představují konfiguraci a tajné údaje vázané na instanci (např. klíče API). Na rozdíl od `applicationVariables` neuvádějí v manifestu žádnou hodnotu — operátor pracovního prostoru je vyplní v nastavení aplikace a do logických funkcí jsou injektovány až poté, co jsou nastaveny.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: Instalační hooky
|
||||
description: Spouštějte logiku před instalací nebo po ní — naplňte data, zazálohujte záznamy, ověřte aktualizaci.
|
||||
description: Spouštějte logiku během životního cyklu instalace, upgradu nebo odinstalace – naplňte data, zálohujte záznamy, ověřte upgrade, vyčistěte externí zdroje.
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
Instalační hooky jsou speciální logické funkce, které se spouštějí během životního cyklu instalace nebo upgradu. Sdílí stejný runtime handleru jako běžné [logické funkce](/l/cs/developers/extend/apps/logic/logic-functions) a přijímají `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` je při čisté instalaci `undefined`), ale deklarují se pomocí vlastních definičních funkcí a fungují mimo běžný model triggerů (HTTP, cron, databázové události).
|
||||
Instalační hooky jsou speciální logické funkce, které se spouštějí během životního cyklu instalace, upgradu nebo odinstalace. Sdílí stejný runtime handleru jako běžné [logické funkce](/l/cs/developers/extend/apps/logic/logic-functions), ale deklarují se pomocí vlastních definičních funkcí a fungují mimo běžný model triggerů (HTTP, cron, databázové události). Instalační hooky přijímají `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` je při čisté instalaci `undefined`); hook pro odinstalaci přijímá `UninstallPayload` (`{ version?: string }` — verze, která se odstraňuje).
|
||||
|
||||
Každá aplikace může definovat **nanejvýš jednu pre-install** a **nanejvýš jednu post-install** funkci. Sestavení manifestu skončí chybou, pokud je zjištěno více než jedno z nich.
|
||||
Každá aplikace smí definovat **nanejvýš jeden** hook každého typu (předinstalační, poinstalační, odinstalační). Sestavení manifestu skončí chybou, pokud je zjištěn více než jeden hook daného typu.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Odinstalační hook
|
||||
|
||||
`defineUninstallLogicFunction` deklaruje hook, který se spustí, když uživatel odinstaluje vaši aplikaci. Spustí se **předtím**, než jsou odstraněna metadata, data a kód aplikace — jakmile se spustí migrační skript pro smazání, nezbude nic, co by se dalo vykonat — takže váš handler může stále dotazovat objekty a záznamy aplikace. Použijte ho k úklidu externích prostředků: zrušení přidělených API prostředků, smazání zbývajících botů, odvolání webhooks.
|
||||
|
||||
Poznámky:
|
||||
|
||||
* Hook pracuje v režimu best effort: běží synchronně, ale chyba se pouze zaloguje a **nikdy neblokuje odinstalaci** — úklid nesmí znemožnit odebrání aplikace.
|
||||
* Přijímá `UninstallPayload` (`{ version?: string }` — verze, která se odstraňuje).
|
||||
* Nespouští se, pokud je neúspěšná čistá instalace vrácena zpět — aplikace nikdy nedokončila instalaci.
|
||||
* Hook nemůže běžet poté, co je aplikace pryč, takže externí úklid, který závisí na datech aplikace (např. ID botů uložená v záznamech), patří sem, ne do externí naplánované úlohy.
|
||||
* Stejně jako instalační hooky se **nespouští v dev módu** — místo toho ho vyvolejte ručně:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ icon: screwdriver-wrench
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ icon: screwdriver-wrench
|
||||
`defineRole` – deklaruje, co mohou logické funkce vaší aplikace číst a zapisovat.
|
||||
</Card>
|
||||
<Card title="Instalační hooky" icon="wrench" href="/l/cs/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` a `definePostInstallLogicFunction` – zálohují data, nastavují výchozí hodnoty, validují aktualizace.
|
||||
`definePreInstallLogicFunction`, `definePostInstallLogicFunction` a `defineUninstallLogicFunction` — zálohují data, nastavují výchozí hodnoty, validují aktualizace, uklízejí při odebrání.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ icon: screwdriver-wrench
|
||||
|
||||
* **Aplikace** je vstupní bod. Každá aplikace má právě jedno volání `defineApplication()`, které ukazuje na jednu **roli** jako výchozí.
|
||||
* **Role** určuje, co mohou logické funkce aplikace a front-endové komponenty číst a zapisovat. Dodržujte zásadu nejmenších oprávnění: udělujte pouze ta oprávnění, která váš kód skutečně potřebuje.
|
||||
* **Instalační hooky** se spouštějí během instalace nebo aktualizace – pre-install před migrací metadat (aby mohly odmítnout rizikovou aktualizaci), post-install po migraci (aby mohly proti novému schématu naplnit výchozí data).
|
||||
* **Instalační hooky** se spouštějí během instalace nebo aktualizace – pre-install před migrací metadat (aby mohly odmítnout rizikovou aktualizaci), post-install po migraci (aby mohly proti novému schématu naplnit výchozí data). Hook pro odinstalaci se spouští těsně před odebráním aplikace, takže může uklidit externí prostředky, zatímco data aplikace jsou stále čitelná.
|
||||
|
||||
<Note>
|
||||
Instalační hooky sdílejí běhové prostředí [logických funkcí](/l/cs/developers/extend/apps/logic/logic-functions) – stejný podpis handleru, stejné proměnné prostředí, stejný typovaný klient API – ale deklarují se pomocí vlastních funkcí define a fungují mimo běžný model spouštěčů (HTTP, cron, databázové události).
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — sleduje vaše zdrojové soubory a průběžně synchronizuje změny s připojeným serverem Twenty. Typovaný klient API se při změně schématu automaticky znovu vygeneruje.
|
||||
* **`yarn twenty dev:build`** — zkompiluje TypeScript, zabalí logické funkce a frontendové komponenty pomocí esbuild a vytvoří manifest.
|
||||
* **Pre/post-install hooks** — volitelné funkce, které běží během instalace. Podrobnosti viz [Install Hooks](/l/cs/developers/extend/apps/config/install-hooks).
|
||||
* **Pre/post-install hooks odinstalace** — volitelné funkce, které běží během instalace nebo těsně před odstraněním. Podrobnosti viz [Install Hooks](/l/cs/developers/extend/apps/config/install-hooks).
|
||||
|
||||
## Další kroky
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Konfigurace" icon="screwdriver-wrench" href="/l/cs/developers/extend/apps/config/overview">
|
||||
Identita aplikace, výchozí role a instalační hooky.
|
||||
Identita aplikace, výchozí role a instalační a odinstalační hooky.
|
||||
</Card>
|
||||
<Card title="Data" icon="database" href="/l/cs/developers/extend/apps/data/overview">
|
||||
Objekty, pole a obousměrné relace.
|
||||
|
||||
@@ -149,7 +149,7 @@ Aplikace se skládají z **entit** — každá je definována jako soubor TypeSc
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Konfigurace" icon="screwdriver-wrench" href="/l/cs/developers/extend/apps/config/overview">
|
||||
Identita aplikace, výchozí role, instalační hooky, veřejná aktiva.
|
||||
Identita aplikace, výchozí role, instalační i odinstalační hooky, veřejná aktiva.
|
||||
</Card>
|
||||
<Card title="Data" icon="database" href="/l/cs/developers/extend/apps/data/overview">
|
||||
Objekty, pole a obousměrné relace.
|
||||
|
||||
@@ -613,7 +613,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**Instalační hooky** — předinstalační a poinstalační handlery — sdílejí toto běhové prostředí, ale deklarují se vlastními funkcemi `define` a nepřebírají nastavení spouštěče (triggeru). Viz [Instalační hooky](/l/cs/developers/extend/apps/config/install-hooks) pro `definePreInstallLogicFunction` a `definePostInstallLogicFunction`.
|
||||
**Instalační hooky** — předinstalační, poinstalační a odinstalační handlery — sdílejí toto běhové prostředí, ale deklarují se vlastními funkcemi `define` a nepřebírají nastavení spouštěče (triggeru). Viz [Instalační hooky](/l/cs/developers/extend/apps/config/install-hooks) pro `definePreInstallLogicFunction`, `definePostInstallLogicFunction` a `defineUninstallLogicFunction`.
|
||||
</Note>
|
||||
|
||||
## Typovaní klienti API (twenty-client-sdk)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## Zobrazení logů funkcí (`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ Jede App muss genau einen Aufruf von `defineApplication` haben. Dieser deklarier
|
||||
* **Identität** — universeller Bezeichner, Anzeigename, Beschreibung.
|
||||
* **Berechtigungen** — unter welcher Rolle ihre Logikfunktionen und Frontend-Komponenten ausgeführt werden.
|
||||
* **Variablen** *(optional)* — Schlüssel–Wert-Paare, die Ihrem Code als Umgebungsvariablen zur Verfügung gestellt werden.
|
||||
* **Pre-install-/Post-install-Hooks** *(optional)* — siehe [Logikfunktionen](/l/de/developers/extend/apps/logic/logic-functions).
|
||||
* **Pre-install-/Post-install-/Uninstall-Hooks** *(optional)* — siehe [Logikfunktionen](/l/de/developers/extend/apps/logic/logic-functions).
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ Notizen:
|
||||
* `universalIdentifier`-Felder sind deterministische IDs, die Ihnen gehören. Erzeugen Sie sie einmal und halten Sie sie über Synchronisierungen hinweg stabil.
|
||||
* `applicationVariables` werden zu Umgebungsvariablen für Ihre Funktionen und Frontend-Komponenten. In Logikfunktionen (serverseitig) sind sie als `process.env.VARIABLE_NAME` verfügbar. In Frontend-Komponenten verwenden Sie `getApplicationVariable('VARIABLE_NAME')` aus `twenty-sdk/front-component`. Variablen, die mit `isSecret: true` gekennzeichnet sind, werden nur in Logikfunktionen injiziert. Frontend-Komponenten erhalten nur nicht-geheime Variablen.
|
||||
* Die Standardrolle wird automatisch aus der Rollen-Datei erkannt, die mit [`defineApplicationRole()`](/l/de/developers/extend/apps/config/roles) markiert ist – Sie müssen sie nicht aus `defineApplication()` referenzieren.
|
||||
* Pre- und Post-Installationsfunktionen werden während des Manifest-Builds automatisch erkannt — Sie müssen sie in `defineApplication()` nicht referenzieren.
|
||||
* Pre-Installations-, Post-Installations- und Deinstallationsfunktionen werden während des Manifest-Builds automatisch erkannt — Sie müssen sie in `defineApplication()` nicht referenzieren.
|
||||
* Die explizite Übergabe von `defaultRoleUniversalIdentifier` wird für die Abwärtskompatibilität weiterhin unterstützt, ist jedoch zugunsten von `defineApplicationRole()` veraltet.
|
||||
* `serverVariables` sind instanzbezogene Konfigurationen und Geheimnisse (z. B. API-Schlüssel). Im Gegensatz zu `applicationVariables` haben sie im Manifest keinen Wert definiert – die Workspace-Operatorin bzw. der Workspace-Operator trägt sie in den App-Einstellungen ein, und sie werden erst dann in Logikfunktionen eingespeist, wenn sie gesetzt sind.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: Installations-Hooks
|
||||
description: Führen Sie Logik vor oder nach der Installation aus – befüllen Sie Daten, sichern Sie Datensätze und validieren Sie das Upgrade.
|
||||
description: Führen Sie Logik während des Installations-, Upgrade- oder Deinstallations-Lebenszyklus aus – initialisieren Sie Daten, sichern Sie Datensätze, validieren Sie das Upgrade, bereinigen Sie externe Ressourcen.
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
Installations-Hooks sind spezielle Logikfunktionen, die während des Installations- oder Upgrade-Lebenszyklus ausgeführt werden. Sie verwenden dieselbe Handler-Laufzeit wie reguläre [Logikfunktionen](/l/de/developers/extend/apps/logic/logic-functions) und erhalten ein `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` ist bei einer Neuinstallation `undefined`), werden jedoch mit eigenen Define-Funktionen deklariert und befinden sich außerhalb des normalen Trigger-Modells (HTTP, Cron, Datenbankereignisse).
|
||||
Installations-Hooks sind spezielle Logikfunktionen, die während des Installations-, Upgrade- oder Deinstallations-Lebenszyklus ausgeführt werden. Sie verwenden dieselbe Handler-Laufzeit wie reguläre [Logikfunktionen](/l/de/developers/extend/apps/logic/logic-functions), werden jedoch mit eigenen Define-Funktionen deklariert und sind vom normalen Trigger-Modell (HTTP, Cron, Datenbankereignisse) getrennt. Installations-Hooks erhalten ein `InstallPayload` (`{ previousVersion?: string; newVersion: string }` – `previousVersion` ist bei einer Neuinstallation `undefined`); der Deinstallations-Hook erhält ein `UninstallPayload` (`{ version?: string }` – die entfernte Version).
|
||||
|
||||
Jede App darf **höchstens eine Pre-Install-Funktion** und **höchstens eine Post-Install-Funktion** definieren. Der Manifest-Build schlägt fehl, wenn mehr als eine von beiden erkannt wird.
|
||||
Jede App darf **höchstens einen** Hook jeder Art definieren (Pre-Install, Post-Install, Uninstall). Der Manifest-Build schlägt fehl, wenn mehr als ein Hook eines Typs erkannt wird.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Deinstallations-Hook
|
||||
|
||||
`defineUninstallLogicFunction` deklariert einen Hook, der ausgeführt wird, wenn ein Benutzer Ihre App deinstalliert. Er wird **ausgeführt, bevor** die Metadaten, Daten und der Code der App entfernt werden – sobald die Löschmigration ausgeführt wurde, bleibt nichts mehr zum Ausführen übrig – sodass Ihr Handler weiterhin die Objekte und Datensätze der App abfragen kann. Verwenden Sie ihn zur Bereinigung externer Ressourcen: Stellen Sie API-Ressourcen außer Betrieb, löschen Sie verbleibende Bots, widerrufen Sie Webhooks.
|
||||
|
||||
Notizen:
|
||||
|
||||
* Der Hook ist Best-Effort: Er wird synchron ausgeführt, aber ein Fehler wird protokolliert und **blockiert die Deinstallation niemals** – die Bereinigung darf es nicht unmöglich machen, eine App zu entfernen.
|
||||
* Er erhält `UninstallPayload` (`{ version?: string }` – die entfernte Version).
|
||||
* Er wird **nicht** ausgeführt, wenn eine fehlgeschlagene Neuinstallation zurückgerollt wird – die App wurde nie vollständig installiert.
|
||||
* Der Hook kann nicht ausgeführt werden, nachdem die App entfernt wurde, daher gehört externe Bereinigung, die von App-Daten abhängt (z. B. in Datensätzen gespeicherte Bot-IDs), hierher und nicht in einen externen geplanten Job.
|
||||
* Wie die Installations-Hooks wird er **nicht im Dev-Modus ausgeführt** – lösen Sie ihn stattdessen manuell aus:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ Die **Konfigurationsebene** einer Twenty-App beschreibt die App *für die Plattf
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ Die **Konfigurationsebene** einer Twenty-App beschreibt die App *für die Plattf
|
||||
`defineRole` – deklariert, was die Logikfunktionen Ihrer App lesen und schreiben können.
|
||||
</Card>
|
||||
<Card title="Installations-Hooks" icon="wrench" href="/l/de/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` und `definePostInstallLogicFunction` – Daten sichern, Standardwerte befüllen, Aktualisierungen validieren.
|
||||
`definePreInstallLogicFunction`, `definePostInstallLogicFunction` und `defineUninstallLogicFunction` – Daten sichern, Standardwerte befüllen, Aktualisierungen validieren, beim Entfernen aufräumen.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ Die **Konfigurationsebene** einer Twenty-App beschreibt die App *für die Plattf
|
||||
|
||||
* **Application** ist der Einstiegspunkt. Jede App hat genau einen `defineApplication()`-Aufruf, und dieser verweist auf eine **Rolle** als Standard.
|
||||
* Die **Rolle** steuert, was die Logikfunktionen und Frontend-Komponenten der App lesen und schreiben können. Folgen Sie dem Prinzip der geringsten Privilegien: Gewähren Sie nur die Berechtigungen, die Ihr Code tatsächlich benötigt.
|
||||
* **Install Hooks** laufen während der Installation oder Aktualisierung – Pre-Install vor der Metadatenmigration (so kann ein riskantes Upgrade abgelehnt werden), Post-Install nach der Migration (so können Standarddaten gegen das neue Schema befüllt werden).
|
||||
* **Install Hooks** laufen während der Installation oder Aktualisierung – Pre-Install vor der Metadatenmigration (so kann ein riskantes Upgrade abgelehnt werden), Post-Install nach der Migration (so können Standarddaten gegen das neue Schema befüllt werden). Der Uninstall-Hook wird direkt ausgeführt, bevor die App entfernt wird, sodass er externe Ressourcen bereinigen kann, während die Daten der App noch lesbar sind.
|
||||
|
||||
<Note>
|
||||
Installations-Hooks nutzen die Laufzeit der [Logikfunktion](/l/de/developers/extend/apps/logic/logic-functions) – gleiche Handler-Signatur, gleiche Umgebungsvariablen, gleicher typisierter API-Client –, werden aber mit ihren eigenen Define-Funktionen deklariert und leben außerhalb des regulären Trigger-Modells (HTTP, Cron, Datenbankereignisse).
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — überwacht Ihre Quelldateien und synchronisiert Änderungen in Echtzeit mit einem verbundenen Twenty-Server. Der typisierte API-Client wird automatisch neu erzeugt, wenn sich das Schema ändert.
|
||||
* **`yarn twenty dev:build`** — kompiliert TypeScript, bündelt Logikfunktionen und Frontend-Komponenten mit esbuild und erzeugt ein Manifest.
|
||||
* **Pre/Post-Install-Hooks** — optionale Funktionen, die während der Installation ausgeführt werden. Details finden Sie unter [Install Hooks](/l/de/developers/extend/apps/config/install-hooks).
|
||||
* **Pre/Post-Install- und Uninstall-Hooks** — optionale Funktionen, die während der Installation oder direkt vor der Entfernung ausgeführt werden. Details finden Sie unter [Install Hooks](/l/de/developers/extend/apps/config/install-hooks).
|
||||
|
||||
## Nächste Schritte
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Konfiguration" icon="screwdriver-wrench" href="/l/de/developers/extend/apps/config/overview">
|
||||
App-Identität, Standardrolle und Install-Hooks.
|
||||
App-Identität, Standardrolle sowie Install- und Uninstall-Hooks.
|
||||
</Card>
|
||||
<Card title="Daten" icon="database" href="/l/de/developers/extend/apps/data/overview">
|
||||
Objekte, Felder und bidirektionale Relationen.
|
||||
|
||||
@@ -149,7 +149,7 @@ Vollständige Referenz: [Konzepte](/l/de/developers/extend/apps/getting-started/
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Konfiguration" icon="screwdriver-wrench" href="/l/de/developers/extend/apps/config/overview">
|
||||
Anwendungsidentität, Standardrolle, Install-Hooks, öffentliche Assets.
|
||||
Anwendungsidentität, Standardrolle, Install- und Deinstallations-Hooks, öffentliche Assets.
|
||||
</Card>
|
||||
<Card title="Daten" icon="database" href="/l/de/developers/extend/apps/data/overview">
|
||||
Objekte, Felder und bidirektionale Relationen.
|
||||
|
||||
@@ -612,7 +612,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**Installations-Hooks** – Vorinstallations- und Nachinstallations-Handler – teilen sich diese Laufzeit, werden aber mit ihren eigenen define-Funktionen deklariert und verwenden keine Trigger-Einstellungen. Siehe [Installations-Hooks](/l/de/developers/extend/apps/config/install-hooks) für `definePreInstallLogicFunction` und `definePostInstallLogicFunction`.
|
||||
**Installations-Hooks** – Vorinstallations-, Nachinstallations- und Deinstallations-Handler – teilen sich diese Laufzeit, werden aber mit ihren eigenen define-Funktionen deklariert und verwenden keine Trigger-Einstellungen. Siehe [Installations-Hooks](/l/de/developers/extend/apps/config/install-hooks) für `definePreInstallLogicFunction`, `definePostInstallLogicFunction` und `defineUninstallLogicFunction`.
|
||||
</Note>
|
||||
|
||||
## Typisierte API-Clients (twenty-client-sdk)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## Funktionsprotokolle ansehen (`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ Cada aplicación debe tener exactamente una llamada a `defineApplication`. Decla
|
||||
* **Identidad** — identificador universal, nombre para mostrar, descripción.
|
||||
* **Permisos** — bajo qué rol se ejecutan sus funciones de lógica y componentes de frontend.
|
||||
* **Variables** *(opcionales)* — pares clave–valor expuestos a tu código como variables de entorno.
|
||||
* **Hooks de preinstalación / postinstalación** *(opcionales)* — consulta [Funciones de lógica](/l/es/developers/extend/apps/logic/logic-functions).
|
||||
* **Hooks de preinstalación / posinstalación / desinstalación** *(opcionales)* — consulta [Funciones de lógica](/l/es/developers/extend/apps/logic/logic-functions).
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ Notas:
|
||||
* Los campos `universalIdentifier` son identificadores deterministas que te pertenecen. Genéralos una vez y mantenlos estables entre sincronizaciones.
|
||||
* `applicationVariables` se convierten en variables de entorno para tus funciones y componentes de frontend. En las funciones lógicas (del lado del servidor), están disponibles como `process.env.VARIABLE_NAME`. En los componentes de frontend, usa `getApplicationVariable('VARIABLE_NAME')` de `twenty-sdk/front-component`. Las variables marcadas con `isSecret: true` solo se inyectan en las funciones lógicas. Los componentes de frontend solo reciben variables no secretas.
|
||||
* El rol predeterminado se detecta automáticamente a partir del archivo de rol marcado con [`defineApplicationRole()`](/l/es/developers/extend/apps/config/roles); no necesitas hacer referencia a él desde `defineApplication()`.
|
||||
* Las funciones de preinstalación y posinstalación se detectan automáticamente durante la compilación del manifiesto; no necesitas referenciarlas en `defineApplication()`.
|
||||
* Las funciones de preinstalación, posinstalación y desinstalación se detectan automáticamente durante la compilación del manifiesto; no necesitas referenciarlas en `defineApplication()`.
|
||||
* Pasar `defaultRoleUniversalIdentifier` explícitamente sigue siendo compatible por motivos de retrocompatibilidad, pero está en desuso en favor de `defineApplicationRole()`.
|
||||
* `serverVariables` son configuraciones y secretos con ámbito de instancia (por ejemplo, claves de API). A diferencia de `applicationVariables`, no declaran ningún valor en el manifiesto: el operador del espacio de trabajo los completa desde la configuración de la aplicación, y se inyectan en las funciones lógicas solo una vez que se han establecido.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
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."
|
||||
description: "Ejecuta lógica durante el ciclo de vida de instalación, actualización o desinstalación: siembra datos, realiza copias de seguridad de registros, valida la actualización, limpia recursos externos."
|
||||
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).
|
||||
Los hooks de instalación son funciones de lógica especiales que se ejecutan durante el ciclo de vida de la instalación, actualización o desinstalación. Comparten el mismo tiempo de ejecución del controlador que las [logic functions](/l/es/developers/extend/apps/logic/logic-functions) normales, pero se declaran con sus propias funciones de definición y están fuera del modelo de desencadenadores normal (HTTP, cron, eventos de base de datos). Los hooks de instalación reciben un `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` es `undefined` en una instalación nueva); el hook de desinstalación recibe un `UninstallPayload` (`{ version?: string }` — la versión que se está eliminando).
|
||||
|
||||
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.
|
||||
Cada aplicación puede definir **como máximo un** hook de cada tipo (preinstalación, postinstalación, desinstalación). La compilación del manifiesto genera un error si se detecta más de uno de cualquier tipo.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Hook de desinstalación
|
||||
|
||||
`defineUninstallLogicFunction` declara un hook que se ejecuta cuando un usuario desinstala tu aplicación. Se ejecuta **antes** de que se eliminen los metadatos, los datos y el código de la aplicación — una vez que se ejecuta la migración de eliminación ya no queda nada que ejecutar — por lo que tu controlador todavía puede consultar los objetos y registros de la aplicación. Úsalo para limpiar recursos externos: cancelar el aprovisionamiento de recursos de API, eliminar bots restantes, revocar webhooks.
|
||||
|
||||
Notas:
|
||||
|
||||
* El hook se ejecuta con el mejor esfuerzo posible: se ejecuta de forma sincrónica, pero si falla se registra el error y **nunca bloquea la desinstalación**; la limpieza no debe hacer que una aplicación sea imposible de eliminar.
|
||||
* Recibe `UninstallPayload` (`{ version?: string }` — la versión que se está eliminando).
|
||||
* **No** se ejecuta cuando se revierte una instalación nueva fallida: la aplicación nunca terminó de instalarse.
|
||||
* El hook no puede ejecutarse después de que la aplicación haya desaparecido, por lo que la limpieza externa que depende de datos de la aplicación (por ejemplo, IDs de bots almacenados en registros) debe realizarse aquí, no en una tarea programada externa.
|
||||
* Al igual que los hooks de instalación, **no se ejecuta en modo de desarrollo**; en su lugar, actívalo manualmente:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ La **capa de configuración** de una app de Twenty es lo que describe la app *a
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ La **capa de configuración** de una app de Twenty es lo que describe la app *a
|
||||
`defineRole`: declara qué pueden leer y escribir las funciones lógicas de tu app.
|
||||
</Card>
|
||||
<Card title="Hooks de instalación" icon="wrench" href="/l/es/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` y `definePostInstallLogicFunction`: hacen copias de seguridad de los datos, cargan valores predeterminados y validan actualizaciones.
|
||||
`definePreInstallLogicFunction`, `definePostInstallLogicFunction` y `defineUninstallLogicFunction`: hacen copias de seguridad de los datos, cargan valores predeterminados, validan actualizaciones y limpian durante la desinstalación.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ La **capa de configuración** de una app de Twenty es lo que describe la app *a
|
||||
|
||||
* **Application** es el punto de entrada. Cada app tiene exactamente una llamada a `defineApplication()`, y apunta a un **Role** como su valor predeterminado.
|
||||
* El **Role** controla qué pueden leer y escribir las funciones lógicas y los componentes de interfaz de la app. Sigue el principio de privilegios mínimos: concede solo los permisos que tu código realmente necesita.
|
||||
* Los **hooks de instalación** se ejecutan durante la instalación o la actualización: el hook de preinstalación antes de la migración de metadatos (para poder rechazar una actualización arriesgada) y el hook de postinstalación después de la migración (para poder cargar datos predeterminados con el nuevo esquema).
|
||||
* Los **hooks de instalación** se ejecutan durante la instalación o la actualización: el hook de preinstalación antes de la migración de metadatos (para poder rechazar una actualización arriesgada) y el hook de postinstalación después de la migración (para poder cargar datos predeterminados con el nuevo esquema). El hook de desinstalación se ejecuta justo antes de que se elimine la aplicación, por lo que puede limpiar recursos externos mientras los datos de la aplicación siguen siendo legibles.
|
||||
|
||||
<Note>
|
||||
Los hooks de instalación comparten el entorno de ejecución de la [función lógica](/l/es/developers/extend/apps/logic/logic-functions): misma firma del handler, mismas variables de entorno, mismo cliente de API tipado, pero se declaran con sus propias funciones de definición y viven fuera del modelo de triggers habitual (HTTP, cron, eventos de base de datos).
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — observa tus archivos fuente y sincroniza en tiempo real los cambios con un servidor de Twenty conectado. El cliente de API tipado se regenera automáticamente cuando cambia el esquema.
|
||||
* **`yarn twenty dev:build`** — compila TypeScript, agrupa las funciones de lógica y los componentes de frontend con esbuild, y produce un manifiesto.
|
||||
* **Hooks de pre/post-instalación** — funciones opcionales que se ejecutan durante la instalación. Consulta [Hooks de instalación](/l/es/developers/extend/apps/config/install-hooks) para más detalles.
|
||||
* **Hooks de pre/post-instalación y desinstalación** — funciones opcionales que se ejecutan durante la instalación o justo antes de la eliminación. Consulta [Hooks de instalación](/l/es/developers/extend/apps/config/install-hooks) para más detalles.
|
||||
|
||||
## Próximos pasos
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Configuración" icon="screwdriver-wrench" href="/l/es/developers/extend/apps/config/overview">
|
||||
Identidad de la aplicación, rol predeterminado y hooks de instalación.
|
||||
Identidad de la aplicación, rol predeterminado y hooks de instalación y desinstalación.
|
||||
</Card>
|
||||
<Card title="Datos" icon="database" href="/l/es/developers/extend/apps/data/overview">
|
||||
Objetos, campos y relaciones bidireccionales.
|
||||
|
||||
@@ -149,7 +149,7 @@ Referencia completa: [Conceptos](/l/es/developers/extend/apps/getting-started/co
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Configuración" icon="screwdriver-wrench" href="/l/es/developers/extend/apps/config/overview">
|
||||
Identidad de la aplicación, rol predeterminado, hooks de instalación y recursos públicos.
|
||||
Identidad de la aplicación, rol predeterminado, hooks de instalación y desinstalación, recursos públicos.
|
||||
</Card>
|
||||
<Card title="Datos" icon="database" href="/l/es/developers/extend/apps/data/overview">
|
||||
Objetos, campos y relaciones bidireccionales.
|
||||
|
||||
@@ -613,7 +613,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**Hooks de instalación** — los controladores de preinstalación y postinstalación — comparten este entorno de ejecución, pero se declaran con sus propias funciones 'define' y no aceptan configuraciones de disparador. Consulta [Hooks de instalación](/l/es/developers/extend/apps/config/install-hooks) para `definePreInstallLogicFunction` y `definePostInstallLogicFunction`.
|
||||
**Hooks de instalación** — los controladores de preinstalación, postinstalación y desinstalación — comparten este entorno de ejecución, pero se declaran con sus propias funciones `define` y no aceptan configuraciones de disparador. Consulta [Hooks de instalación](/l/es/developers/extend/apps/config/install-hooks) para `definePreInstallLogicFunction`, `definePostInstallLogicFunction` y `defineUninstallLogicFunction`.
|
||||
</Note>
|
||||
|
||||
## Clientes de API tipados (twenty-client-sdk)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## Ver registros de funciones (`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ Chaque application doit avoir exactement un appel à `defineApplication`. Il dé
|
||||
* **Identité** — identifiant universel, nom d'affichage, description.
|
||||
* **Autorisations** — le rôle sous lequel s'exécutent ses fonctions logiques et ses composants front-end.
|
||||
* **Variables** *(facultatif)* — paires clé–valeur exposées à votre code en tant que variables d'environnement.
|
||||
* **Hooks de pré-installation / post-installation** *(facultatif)* — voir [Fonctions logiques](/l/fr/developers/extend/apps/logic/logic-functions).
|
||||
* **Hooks de pré-installation / post-installation / désinstallation** *(facultatif)* — voir [Fonctions logiques](/l/fr/developers/extend/apps/logic/logic-functions).
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ Notes :
|
||||
* Les champs `universalIdentifier` sont des identifiants déterministes que vous contrôlez. Générez-les une fois et conservez-les stables entre les synchronisations.
|
||||
* `applicationVariables` deviennent des variables d'environnement pour vos fonctions et vos composants front-end. Dans les fonctions logiques (côté serveur), elles sont disponibles sous `process.env.VARIABLE_NAME`. Dans les composants front-end, utilisez `getApplicationVariable('VARIABLE_NAME')` depuis `twenty-sdk/front-component`. Les variables marquées avec `isSecret: true` sont uniquement injectées dans les fonctions logiques. Les composants front-end ne reçoivent que des variables non secrètes.
|
||||
* Le rôle par défaut est détecté automatiquement à partir du fichier de rôle marqué avec [`defineApplicationRole()`](/l/fr/developers/extend/apps/config/roles) — vous n’avez pas besoin d’y faire référence depuis `defineApplication()`.
|
||||
* Les fonctions de pré-installation et de post-installation sont détectées automatiquement lors de la construction du manifeste — vous n'avez pas besoin de les référencer dans `defineApplication()`.
|
||||
* Les fonctions de pré-installation, de post-installation et de désinstallation sont détectées automatiquement lors de la construction du manifeste — vous n'avez pas besoin de les référencer dans `defineApplication()`.
|
||||
* Le passage explicite de `defaultRoleUniversalIdentifier` est toujours pris en charge pour des raisons de rétrocompatibilité, mais il est obsolète au profit de `defineApplicationRole()`.
|
||||
* `serverVariables` sont des configurations et des secrets au niveau de l’instance (par exemple des clés d’API). Contrairement à `applicationVariables`, ils ne déclarent aucune valeur dans le manifeste — l’opérateur de l’espace de travail les renseigne dans les paramètres de l’application, et ils sont injectés dans les fonctions logiques uniquement une fois définis.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: Hooks d'installation
|
||||
description: Exécutez de la logique avant ou après l'installation — initialisez des données, sauvegardez des enregistrements, validez la mise à niveau.
|
||||
description: Exécutez de la logique pendant le cycle de vie d'installation, de mise à niveau ou de désinstallation — préremplissez des données, sauvegardez des enregistrements, validez la mise à niveau, nettoyez les ressources externes.
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
Les hooks d'installation sont des fonctions logiques spéciales qui s'exécutent pendant le cycle de vie d'installation ou de mise à niveau. Ils partagent le même environnement d'exécution que les [fonctions logiques](/l/fr/developers/extend/apps/logic/logic-functions) classiques et reçoivent un `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` est `undefined` lors d'une nouvelle installation), mais ils sont déclarés avec leurs propres fonctions de définition et ne relèvent pas du modèle de déclencheur habituel (HTTP, cron, événements de base de données).
|
||||
Les hooks d'installation sont des fonctions logiques spéciales qui s'exécutent pendant le cycle de vie d'installation, de mise à niveau ou de désinstallation. Ils partagent le même environnement d'exécution que les [fonctions logiques](/l/fr/developers/extend/apps/logic/logic-functions) classiques, mais ils sont déclarés avec leurs propres fonctions de définition et ne relèvent pas du modèle de déclencheur habituel (HTTP, cron, événements de base de données). Les hooks d'installation reçoivent un `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` est `undefined` lors d'une nouvelle installation) ; le hook de désinstallation reçoit un `UninstallPayload` (`{ version?: string }` — la version supprimée).
|
||||
|
||||
Chaque application peut définir **au maximum une pré-installation** et **au maximum une post-installation**. La génération du manifeste renvoie une erreur si plus d'une fonction de l'un ou l'autre type est détectée.
|
||||
Chaque application peut définir **au maximum un seul** hook de chaque type (pré-installation, post-installation, désinstallation). La génération du manifeste renvoie une erreur si plus d'un hook de n'importe quel type est détecté.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Hook de désinstallation
|
||||
|
||||
`defineUninstallLogicFunction` déclare un hook qui s'exécute lorsqu'un utilisateur désinstalle votre application. Il s'exécute **avant** que les métadonnées, les données et le code de l'application ne soient supprimés — une fois que la migration de suppression est exécutée, il ne reste plus rien à exécuter — de sorte que votre gestionnaire peut encore interroger les objets et enregistrements de l'application. Utilisez-le pour nettoyer les ressources externes : déprovisionner les ressources d'API, supprimer les bots restants, révoquer les webhooks.
|
||||
|
||||
Notes :
|
||||
|
||||
* Le hook fonctionne selon le principe du "best effort" : il s'exécute de manière synchrone, mais un échec est consigné dans les journaux et **ne bloque jamais la désinstallation** — le nettoyage ne doit pas rendre une application impossible à supprimer.
|
||||
* Il reçoit `UninstallPayload` (`{ version?: string }` — la version supprimée).
|
||||
* Il **ne** s'exécute **pas** lorsqu'une nouvelle installation ayant échoué est annulée — l'application n'a jamais terminé son installation.
|
||||
* Le hook ne peut pas s'exécuter après la suppression de l'application, donc le nettoyage externe qui dépend des données de l'application (par exemple des identifiants de bots stockés dans des enregistrements) doit être effectué ici, et non dans une tâche planifiée externe.
|
||||
* Comme les hooks d'installation, il **n'est pas exécuté en mode dev** — déclenchez-le manuellement à la place :
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ La **couche de configuration** d'une application Twenty est ce qui décrit l'app
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ La **couche de configuration** d'une application Twenty est ce qui décrit l'app
|
||||
`defineRole` — déclarez ce que les fonctions logiques de votre application peuvent lire et écrire.
|
||||
</Card>
|
||||
<Card title="Hooks d'installation" icon="wrench" href="/l/fr/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` et `definePostInstallLogicFunction` — sauvegarder les données, préremplir les valeurs par défaut, valider les mises à niveau.
|
||||
`definePreInstallLogicFunction`, `definePostInstallLogicFunction` et `defineUninstallLogicFunction` — sauvegarder les données, préremplir les valeurs par défaut, valider les mises à niveau, nettoyer lors de la suppression.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ La **couche de configuration** d'une application Twenty est ce qui décrit l'app
|
||||
|
||||
* L'**application** est le point d'entrée. Chaque application comporte exactement un appel à `defineApplication()` qui pointe vers un **Rôle** par défaut.
|
||||
* Le **Rôle** contrôle ce que les fonctions logiques et les composants frontaux de l'application peuvent lire et écrire. Suivez le principe du moindre privilège : accordez uniquement les autorisations dont votre code a réellement besoin.
|
||||
* Les **hooks d'installation** s'exécutent lors de l'installation ou de la mise à niveau — la pré-installation avant la migration des métadonnées (ce qui permet de refuser une mise à niveau risquée), la post-installation après la migration (ce qui permet de préremplir les données par défaut selon le nouveau schéma).
|
||||
* Les **hooks d'installation** s'exécutent lors de l'installation ou de la mise à niveau — la pré-installation avant la migration des métadonnées (ce qui permet de refuser une mise à niveau risquée), la post-installation après la migration (ce qui permet de préremplir les données par défaut selon le nouveau schéma). Le hook de désinstallation s’exécute juste avant que l’application ne soit supprimée, ce qui lui permet de nettoyer les ressources externes tant que les données de l’application sont encore lisibles.
|
||||
|
||||
<Note>
|
||||
Les hooks d'installation partagent l'environnement d'exécution des [fonctions logiques](/l/fr/developers/extend/apps/logic/logic-functions) — même signature de handler, mêmes variables d'environnement, même client d'API typé — mais ils sont déclarés avec leurs propres fonctions `define` et vivent en dehors du modèle de déclencheurs habituel (HTTP, cron, événements de base de données).
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — surveille vos fichiers source et synchronise en direct les modifications avec un serveur Twenty connecté. Le client d’API typé est régénéré automatiquement lorsque le schéma change.
|
||||
* **`yarn twenty dev:build`** — compile TypeScript, regroupe les fonctions logiques et les composants frontaux avec esbuild, et produit un manifeste.
|
||||
* **Hooks pré/post-install** — fonctions optionnelles qui s’exécutent pendant l’installation. Voir [Install Hooks](/l/fr/developers/extend/apps/config/install-hooks) pour plus de détails.
|
||||
* **Hooks pré/post-install et de désinstallation** — fonctions optionnelles qui s’exécutent pendant l’installation ou juste avant la suppression. Voir [Install Hooks](/l/fr/developers/extend/apps/config/install-hooks) pour plus de détails.
|
||||
|
||||
## Prochaines étapes
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Configuration" icon="screwdriver-wrench" href="/l/fr/developers/extend/apps/config/overview">
|
||||
Identité de l’application, rôle par défaut et hooks d’installation.
|
||||
Identité de l’application, rôle par défaut et hooks d’installation et de désinstallation.
|
||||
</Card>
|
||||
<Card title="Données" icon="database" href="/l/fr/developers/extend/apps/data/overview">
|
||||
Objets, champs et relations bidirectionnelles.
|
||||
|
||||
@@ -149,7 +149,7 @@ Référence complète : [Concepts](/l/fr/developers/extend/apps/getting-started/
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Configuration" icon="screwdriver-wrench" href="/l/fr/developers/extend/apps/config/overview">
|
||||
Identité de l’application, rôle par défaut, hooks d’installation, ressources publiques.
|
||||
Identité de l’application, rôle par défaut, hooks d’installation et de désinstallation, ressources publiques.
|
||||
</Card>
|
||||
<Card title="Données" icon="database" href="/l/fr/developers/extend/apps/data/overview">
|
||||
Objets, champs et relations bidirectionnelles.
|
||||
|
||||
@@ -283,7 +283,7 @@ L’identifiant est le `universalIdentifier` du résolveur issu de votre manifes
|
||||
**L’application doit être revendiquée et installée sur son espace de travail propriétaire.** Comme le résolveur s’exécute dans l’**espace de travail propriétaire** (l’espace de travail qui détient l’enregistrement de l’application), un déclencheur de route serveur ne fonctionne que lorsque l’application a été *revendiquée* — c’est‑à‑dire qu’elle possède un espace de travail propriétaire — **et** que cette application est **installée sur l’espace de travail propriétaire**. Tant que ces deux conditions ne sont pas remplies, le résolveur n’a nulle part où s’exécuter, donc la route ne peut pas être envoyée. Une application qui expose une fonction logique `serverRouteTriggerSettings` ne peut donc pas être répertoriée sur la place de marché tant qu’elle n’a pas été revendiquée et installée sur son espace de travail propriétaire.
|
||||
</Note>
|
||||
|
||||
**Contrat du résolveur.** Le type `LogicFunctionConfig` du SDK impose cela à la compilation : dès que vous définissez `serverRouteTriggerSettings`, votre gestionnaire est contraint de retourner soit un `Response`, soit `{ workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object }` (ou une `Promise` de l’un ou l’autre). Sur le chemin de dispatch, le `workspaceId` doit être celui d’un espace de travail où la fonction cible est installée, sinon la requête est rejetée avec un `404`. Un résultat qui ne correspond à aucune de ces formes — y compris un résultat dont les identifiants ne sont pas des UUID — est rejeté avec un `502`.
|
||||
**Contrat du résolveur.** Le type `LogicFunctionConfig` du SDK impose cela à la compilation : dès que vous définissez `serverRouteTriggerSettings`, votre gestionnaire est contraint de retourner soit un `Response`, soit `{ workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object }` (ou une `Promise` de l’un ou l’autre). Sur le chemin d’acheminement, le `workspaceId` doit être celui d’un espace de travail où la fonction cible est installée, sinon la requête est rejetée avec un `404`. Un résultat qui ne correspond à aucune de ces formes — y compris un résultat dont les identifiants ne sont pas des UUID — est rejeté avec un `502`.
|
||||
|
||||
| Champ | Type | Notes |
|
||||
| ---------------------------------------- | --------------------- | -------------------------------------------------------------------------------------- |
|
||||
@@ -308,9 +308,9 @@ Pour les signatures de requêtes, la plupart des fournisseurs signent avec HMAC-
|
||||
L’exemple de résolveur ci-dessus montre déjà le flux GitHub HMAC-SHA256 — adaptez le nom de l’en-tête, l’encodage de l’empreinte et la chaîne de la charge utile signée en fonction du fournisseur avec lequel vous vous intégrez.
|
||||
|
||||
<Note>
|
||||
Lorsque le résolveur retourne un objet de dispatch, la route répond `202 { queued: true }` et la cible s’exécute dans la file d’attente du worker — l’appelant n’observe jamais la latence, le résultat ou les échecs de la cible (ceux-ci sont enregistrés dans les journaux d’exécution). Cela évite que les nouvelles tentatives d’envoi de l’émetteur n’amplifient les ralentissements de traitement, ce qui est souhaitable pour l’ingestion de webhook.
|
||||
Lorsque le résolveur retourne un objet d’acheminement, la route répond `202 { queued: true }` et la cible s’exécute dans la file d’attente du worker — l’appelant n’observe jamais la latence, le résultat ou les échecs de la cible (ceux-ci sont enregistrés dans les journaux d’exécution). Cela évite que les nouvelles tentatives d’envoi de l’émetteur n’amplifient les ralentissements de traitement, ce qui est souhaitable pour l’ingestion de webhook.
|
||||
|
||||
Lorsque l’appelant doit lire le corps de la réponse sur la même requête (handshakes de challenge, accusés de réception interactifs), retournez plutôt un `Response` depuis le **résolveur**. La plateforme le renvoie en écho de manière synchrone et ignore la file d’attente ; ses en-têtes passent par la même liste d’autorisation que les réponses de routes HTTP. Gardez le résolveur rapide — certains fournisseurs (par ex. Slack) ont un délai d’attente de seulement quelques secondes. Comme le résolveur est accessible en tant que point de terminaison public, protégez-le avec une limitation de débit à votre périphérie.
|
||||
Lorsque l’appelant doit lire le corps de la réponse sur la même requête (handshakes de challenge, accusés de réception interactifs), retournez plutôt un `Response` depuis le **résolveur**. La plateforme le renvoie de manière synchrone et ignore la file d’attente ; ses en-têtes passent par la même liste d’autorisation que les réponses des routes HTTP. Gardez le résolveur rapide — certains fournisseurs (par ex. Slack) ont un délai d’attente de seulement quelques secondes. Comme le résolveur est accessible en tant que point de terminaison public, protégez-le avec une limitation de débit à votre périphérie.
|
||||
</Note>
|
||||
|
||||
#### Charge utile du déclencheur d'événement de base de données
|
||||
@@ -613,7 +613,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**Hooks d'installation** — les gestionnaires de pré-installation et de post-installation — partagent ce runtime mais sont déclarés avec leurs propres fonctions define et ne prennent pas de paramètres de déclenchement. Voir [hooks d'installation](/l/fr/developers/extend/apps/config/install-hooks) pour `definePreInstallLogicFunction` et `definePostInstallLogicFunction`.
|
||||
**Hooks d'installation** — les gestionnaires de pré-installation, de post-installation et de désinstallation — partagent ce runtime mais sont déclarés avec leurs propres fonctions define et ne prennent pas de paramètres de déclenchement. Voir [hooks d'installation](/l/fr/developers/extend/apps/config/install-hooks) pour `definePreInstallLogicFunction`, `definePostInstallLogicFunction` et `defineUninstallLogicFunction`.
|
||||
</Note>
|
||||
|
||||
## Clients d'API typés (twenty-client-sdk)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## Afficher les journaux des fonctions (`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ Ogni app deve avere esattamente una chiamata a `defineApplication`. Dichiara:
|
||||
* **Identità** — identificatore universale, nome visualizzato, descrizione.
|
||||
* **Autorizzazioni** — il ruolo sotto il quale vengono eseguite le sue funzioni logiche e i componenti front-end.
|
||||
* **Variabili** *(opzionali)* — coppie chiave–valore esposte al tuo codice come variabili d'ambiente.
|
||||
* **Hook di pre-installazione / post-installazione** *(opzionali)* — vedi [Funzioni logiche](/l/it/developers/extend/apps/logic/logic-functions).
|
||||
* **Hook di pre-installazione / post-installazione / disinstallazione** *(opzionali)* — vedi [Funzioni logiche](/l/it/developers/extend/apps/logic/logic-functions).
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ Note:
|
||||
* I campi `universalIdentifier` sono ID deterministici che possiedi. Generali una volta e mantienili stabili tra una sincronizzazione e l'altra.
|
||||
* `applicationVariables` diventano variabili d'ambiente per le tue funzioni e i componenti front-end. Nelle funzioni di logica (lato server), sono disponibili come `process.env.VARIABLE_NAME`. Nei componenti front-end, usa `getApplicationVariable('VARIABLE_NAME')` da `twenty-sdk/front-component`. Le variabili contrassegnate con `isSecret: true` vengono iniettate solo nelle funzioni di logica. I componenti front-end ricevono solo variabili non segrete.
|
||||
* Il ruolo predefinito viene rilevato automaticamente dal file di ruolo contrassegnato con [`defineApplicationRole()`](/l/it/developers/extend/apps/config/roles): non è necessario farvi riferimento da `defineApplication()`.
|
||||
* Le funzioni di pre-installazione e post-installazione vengono rilevate automaticamente durante il build del manifest — non è necessario farne riferimento in `defineApplication()`.
|
||||
* Le funzioni di pre-installazione, post-installazione e disinstallazione vengono rilevate automaticamente durante il build del manifest — non è necessario farne riferimento in `defineApplication()`.
|
||||
* Il passaggio esplicito di `defaultRoleUniversalIdentifier` è ancora supportato per garantire la compatibilità con le versioni precedenti, ma è deprecato a favore di `defineApplicationRole()`.
|
||||
* `serverVariables` sono configurazioni e segreti con ambito di istanza (ad esempio chiavi API). A differenza di `applicationVariables`, non dichiarano alcun valore nel manifest — l’operatore dello spazio di lavoro li compila dalle impostazioni dell’app e vengono iniettati nelle funzioni di logica solo una volta impostati.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: Hook di installazione
|
||||
description: Esegui logica prima o dopo l'installazione — popola i dati, esegui il backup dei record, convalida l'aggiornamento.
|
||||
description: Esegui la logica durante il ciclo di vita di installazione, aggiornamento o disinstallazione — inserisci dati iniziali, esegui il backup dei record, valida l'aggiornamento, pulisci le risorse esterne.
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
Gli hook di installazione sono funzioni logiche speciali che vengono eseguite durante il ciclo di vita di installazione o aggiornamento. Condividono lo stesso runtime del gestore delle [logic functions](/l/it/developers/extend/apps/logic/logic-functions) normali e ricevono un `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` è `undefined` in una nuova installazione), ma sono dichiarati con le proprie funzioni di definizione e vivono al di fuori del normale modello di trigger (HTTP, cron, eventi del database).
|
||||
Gli hook di installazione sono funzioni logiche speciali che vengono eseguite durante il ciclo di vita di installazione, aggiornamento o disinstallazione. Condividono lo stesso runtime del gestore delle [logic functions](/l/it/developers/extend/apps/logic/logic-functions) normali, ma sono dichiarati con le proprie funzioni di definizione e vivono al di fuori del normale modello di trigger (HTTP, cron, eventi del database). Gli hook di installazione ricevono un `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` è `undefined` in caso di nuova installazione); l'hook di disinstallazione riceve un `UninstallPayload` (`{ version?: string }` — la versione che viene rimossa).
|
||||
|
||||
Ogni app può definire **al massimo una funzione di pre-installazione** e **al massimo una funzione di post-installazione**. La build del manifesto genera un errore se ne viene rilevata più di una per ciascun tipo.
|
||||
Ogni app può definire **al massimo uno** per ciascun hook (pre-install, post-install, uninstall). La build del manifesto genera un errore se viene rilevato più di un hook per qualsiasi tipo.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Hook di disinstallazione
|
||||
|
||||
`defineUninstallLogicFunction` dichiara un hook che viene eseguito quando un utente disinstalla la tua app. Viene eseguito **prima** che i metadati, i dati e il codice dell'app vengano rimossi — una volta eseguita la migrazione di eliminazione non rimane più nulla da eseguire — quindi il tuo gestore può ancora interrogare gli oggetti e i record dell'app. Usalo per la pulizia delle risorse esterne: deprovisioning delle risorse API, eliminazione dei bot rimanenti, revoca dei webhook.
|
||||
|
||||
Note:
|
||||
|
||||
* L'hook è "best-effort": viene eseguito in modo sincrono, ma un errore viene registrato e **non blocca mai la disinstallazione** — la pulizia non deve rendere impossibile rimuovere un'app.
|
||||
* Riceve `UninstallPayload` (`{ version?: string }` — la versione che viene rimossa).
|
||||
* Non viene eseguito quando un tentativo di nuova installazione non riuscito viene annullato — l'app non ha mai terminato l'installazione.
|
||||
* L'hook non può essere eseguito dopo che l'app è stata rimossa, quindi la pulizia esterna che dipende dai dati dell'app (ad es. ID dei bot memorizzati nei record) deve essere eseguita qui, non in un job pianificato esterno.
|
||||
* Come gli hook di installazione, **non viene eseguito in modalità dev** — attivalo manualmente invece:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ Il **config layer** di un'app Twenty è ciò che descrive l'app *alla piattaform
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ Il **config layer** di un'app Twenty è ciò che descrive l'app *alla piattaform
|
||||
`defineRole` — dichiara ciò che le funzioni logiche della tua app possono leggere e scrivere.
|
||||
</Card>
|
||||
<Card title="Hook di installazione" icon="wrench" href="/l/it/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` e `definePostInstallLogicFunction` — esegui il backup dei dati, imposta i valori predefiniti, convalida gli aggiornamenti.
|
||||
`definePreInstallLogicFunction`, `definePostInstallLogicFunction` e `defineUninstallLogicFunction` — esegui il backup dei dati, imposta i valori predefiniti, convalida gli aggiornamenti, pulisci al momento della rimozione.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ Il **config layer** di un'app Twenty è ciò che descrive l'app *alla piattaform
|
||||
|
||||
* L'**applicazione** è il punto di ingresso. Ogni app ha esattamente una chiamata a `defineApplication()` e punta a un **Ruolo** come predefinito.
|
||||
* Il **Ruolo** controlla ciò che le funzioni di logica e i componenti front-end dell'app possono leggere e scrivere. Segui il principio del privilegio minimo: concedi solo le autorizzazioni di cui il tuo codice ha effettivamente bisogno.
|
||||
* Gli **hook di installazione** vengono eseguiti durante l'installazione o l'aggiornamento — pre-installazione prima della migrazione dei metadati (così può rifiutare un aggiornamento rischioso), post-installazione dopo la migrazione (così può inserire dati predefiniti in base al nuovo schema).
|
||||
* Gli **hook di installazione** vengono eseguiti durante l'installazione o l'aggiornamento — pre-installazione prima della migrazione dei metadati (così può rifiutare un aggiornamento rischioso), post-installazione dopo la migrazione (così può inserire dati predefiniti in base al nuovo schema). L'hook di disinstallazione viene eseguito subito prima che l'app venga rimossa, in modo da poter ripulire le risorse esterne mentre i dati dell'app sono ancora leggibili.
|
||||
|
||||
<Note>
|
||||
Gli hook di installazione condividono il runtime delle [logic function](/l/it/developers/extend/apps/logic/logic-functions) — stessa firma dell'handler, stesse variabili d'ambiente, stesso client API tipizzato — ma sono dichiarati con le proprie funzioni `define` e vivono al di fuori del normale modello di trigger (HTTP, cron, eventi del database).
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — monitora i file sorgente e sincronizza in tempo reale le modifiche su un server Twenty connesso. Il client API tipizzato viene rigenerato automaticamente quando lo schema cambia.
|
||||
* **`yarn twenty dev:build`** — compila TypeScript, crea i bundle delle funzioni logiche e dei componenti front-end con esbuild e produce un manifest.
|
||||
* **Hook di pre/post-installazione** — funzioni opzionali che vengono eseguite durante l’installazione. Vedi [Hook di installazione](/l/it/developers/extend/apps/config/install-hooks) per i dettagli.
|
||||
* **Hook di pre/post-installazione e disinstallazione** — funzioni opzionali che vengono eseguite durante l’installazione o subito prima della rimozione. Vedi [Hook di installazione](/l/it/developers/extend/apps/config/install-hooks) per i dettagli.
|
||||
|
||||
## Prossimi passaggi
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Configurazione" icon="screwdriver-wrench" href="/l/it/developers/extend/apps/config/overview">
|
||||
Identità dell’applicazione, ruolo predefinito e hook di installazione.
|
||||
Identità dell’applicazione, ruolo predefinito e hook di installazione e disinstallazione.
|
||||
</Card>
|
||||
<Card title="Dati" icon="database" href="/l/it/developers/extend/apps/data/overview">
|
||||
Oggetti, campi e relazioni bidirezionali.
|
||||
|
||||
@@ -149,7 +149,7 @@ Riferimento completo: [Concetti](/l/it/developers/extend/apps/getting-started/co
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Configurazione" icon="screwdriver-wrench" href="/l/it/developers/extend/apps/config/overview">
|
||||
Identità dell'applicazione, ruolo predefinito, hook di installazione, asset pubblici.
|
||||
Identità dell'applicazione, ruolo predefinito, hook di installazione e disinstallazione, asset pubblici.
|
||||
</Card>
|
||||
<Card title="Dati" icon="database" href="/l/it/developers/extend/apps/data/overview">
|
||||
Oggetti, campi e relazioni bidirezionali.
|
||||
|
||||
@@ -612,7 +612,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**Hook di installazione** — i gestori di pre-installazione e post-installazione — condividono questo runtime, ma sono dichiarati con le proprie funzioni di definizione e non accettano impostazioni dei trigger. Consulta [Hook di installazione](/l/it/developers/extend/apps/config/install-hooks) per `definePreInstallLogicFunction` e `definePostInstallLogicFunction`.
|
||||
**Hook di installazione** — i gestori di pre-installazione, post-installazione e disinstallazione — condividono questo runtime, ma sono dichiarati con le proprie funzioni di definizione e non accettano impostazioni dei trigger. Consulta [Hook di installazione](/l/it/developers/extend/apps/config/install-hooks) per `definePreInstallLogicFunction`, `definePostInstallLogicFunction` e `defineUninstallLogicFunction`.
|
||||
</Note>
|
||||
|
||||
## Client API tipizzati (twenty-client-sdk)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## Visualizzazione dei log delle funzioni (`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ icon: rocket
|
||||
* **Identity** — ユニバーサル識別子、表示名、説明。
|
||||
* **Permissions** — ロジック関数およびフロントコンポーネントがどのロールで実行されるか。
|
||||
* **Variables** *(optional)* — コードから環境変数として利用できるキーと値のペア。
|
||||
* **Pre-install / post-install hooks** *(optional)* — [Logic Functions](/l/ja/developers/extend/apps/logic/logic-functions) を参照してください。
|
||||
* **プレインストール / ポストインストール / アンインストール フック** *(任意)* — [Logic Functions](/l/ja/developers/extend/apps/logic/logic-functions) を参照してください。
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ export default defineApplication({
|
||||
* `universalIdentifier` フィールドは、あなたが所有する安定した ID です。 一度生成し、その後の同期でも安定して維持してください。
|
||||
* `applicationVariables` は関数やフロントコンポーネントの環境変数になります。 ロジック関数(サーバーサイド)では、`process.env.VARIABLE_NAME` として利用できます。 フロントコンポーネントでは、`twenty-sdk/front-component` の `getApplicationVariable('VARIABLE_NAME')` を使用します。 `isSecret: true` が指定された変数は、ロジック関数にのみインジェクトされます。 フロントコンポーネントには、秘密ではない変数のみが渡されます。
|
||||
* デフォルトのロールは、[`defineApplicationRole()`](/l/ja/developers/extend/apps/config/roles) でマークされたロールファイルから自動的に検出されます。`defineApplication()` から参照する必要はありません。
|
||||
* プレインストール関数とポストインストール関数は、マニフェストのビルド中に自動検出されます—`defineApplication()` で参照する必要はありません。
|
||||
* プレインストール関数、ポストインストール関数、およびアンインストール関数は、マニフェストのビルド中に自動的に検出されるため、`defineApplication()` で参照する必要はありません。
|
||||
* 後方互換性のために `defaultRoleUniversalIdentifier` を明示的に渡すことも依然としてサポートされていますが、`defineApplicationRole()` が推奨されるため、非推奨となっています。
|
||||
* `serverVariables` はインスタンス単位の構成およびシークレット(例: API キー)です。 `applicationVariables` と異なり、マニフェスト内で値は宣言されません。ワークスペースのオペレーターがアプリの設定からそれらを入力し、設定された時点でのみロジック関数に注入されます。
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: インストールフック
|
||||
description: インストールの前後にロジックを実行して、シードデータの投入、レコードのバックアップ、アップグレードの検証を行います。
|
||||
description: インストール、アップグレード、アンインストールのライフサイクル中にロジックを実行し、データのシード、レコードのバックアップ、アップグレードの検証、外部リソースのクリーンアップを行います。
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
インストールフックは、インストールまたはアップグレードのライフサイクル中に実行される特別なロジック関数です。 これらは通常の[ロジック関数](/l/ja/developers/extend/apps/logic/logic-functions)と同じハンドラーランタイムを共有し、`InstallPayload`(`{ previousVersion?: string; newVersion: string }` — 新規インストールでは `previousVersion` は `undefined`)を受け取りますが、独自の define 関数で宣言され、通常のトリガーモデル (HTTP、cron、データベースイベント) の外側で動作します。
|
||||
インストールフックは、インストール、アップグレード、またはアンインストールのライフサイクル中に実行される特別なロジック関数です。 これらは通常の[ロジック関数](/l/ja/developers/extend/apps/logic/logic-functions)と同じハンドラーランタイムを共有しますが、独自の define 関数で宣言され、通常のトリガーモデル (HTTP、cron、データベースイベント) の外側で動作します。 インストールフックは `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — 新規インストールでは `previousVersion` は `undefined`) を受け取り、アンインストールフックは `UninstallPayload` (`{ version?: string }` — 削除されるバージョン) を受け取ります。
|
||||
|
||||
各アプリは、**プレインストール関数は最大 1 つ**、**ポストインストール関数も最大 1 つ**まで定義できます。 どちらかが複数検出された場合、マニフェストのビルドはエラーになります。
|
||||
各アプリは、各フック (プレインストール、ポストインストール、アンインストール) を **最大 1 つまで** 定義できます。 いずれかが複数検出された場合、マニフェストのビルドはエラーになります。
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## アンインストールフック
|
||||
|
||||
`defineUninstallLogicFunction` は、ユーザーがアプリをアンインストールしたときに実行されるフックを宣言します。 これは、アプリのメタデータ、データ、コードが削除される **前に** 実行されます。削除マイグレーションが実行された後には、実行できるものは何も残らないため、ハンドラーはまだアプリのオブジェクトやレコードをクエリできます。 これを、外部リソースのクリーンアップに使用します。API リソースのプロビジョニング解除、残っているボットの削除、webhook の失効などです。
|
||||
|
||||
注記:
|
||||
|
||||
* このフックはベストエフォートで動作します。同期的に実行されますが、失敗してもログに記録されるだけであり、**アンインストールをブロックすることは決してありません**。クリーンアップ処理が原因でアプリを削除できなくなってはなりません。
|
||||
* これは `UninstallPayload` (`{ version?: string }` — 削除されるバージョン) を受け取ります。
|
||||
* 新規インストールの失敗によりロールバックされた場合には実行されません。アプリのインストールが最後まで完了していないためです。
|
||||
* このフックは、アプリが削除された後には実行できないため、アプリデータ (レコードに保存されたボット ID など) に依存する外部クリーンアップ処理は、外部のスケジュールジョブではなく、ここに実装する必要があります。
|
||||
* インストールフックと同様に、これは **dev モードでは実行されません**。代わりに手動でトリガーしてください:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ Twenty アプリの **config layer** は、アプリのアイデンティティ
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ Twenty アプリの **config layer** は、アプリのアイデンティティ
|
||||
`defineRole` — アプリのロジック関数が読み書きできる内容を宣言します。
|
||||
</Card>
|
||||
<Card title="インストールフック" icon="wrench" href="/l/ja/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` と `definePostInstallLogicFunction` — データのバックアップ、デフォルト値の投入、アップグレードの検証を行います。
|
||||
`definePreInstallLogicFunction`、`definePostInstallLogicFunction`、および `defineUninstallLogicFunction` — データのバックアップ、デフォルト値の投入、アップグレードの検証、アンインストール時のクリーンアップを行います。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ Twenty アプリの **config layer** は、アプリのアイデンティティ
|
||||
|
||||
* **アプリケーション** がエントリポイントです。 すべてのアプリには `defineApplication()` 呼び出しが 1 つだけ存在し、その呼び出しは 1 つの **ロール** をデフォルトとして指します。
|
||||
* **ロール** は、アプリのロジック関数とフロントコンポーネントが読み書きできる内容を制御します。 最小権限の原則に従い、コードが実際に必要とする権限だけを付与してください。
|
||||
* **インストールフック** はインストールまたはアップグレード時に実行されます。メタデータのマイグレーション前にプレインストールが実行されるため(リスクの高いアップグレードを拒否できます)、マイグレーション後にポストインストールが実行され(新しいスキーマに対してデフォルトデータを投入できます)。
|
||||
* **インストールフック** はインストールまたはアップグレード時に実行されます。メタデータのマイグレーション前にプレインストールが実行されるため(リスクの高いアップグレードを拒否できます)、マイグレーション後にポストインストールが実行され(新しいスキーマに対してデフォルトデータを投入できます)。 アンインストールフックはアプリが削除される直前に実行されるため、アプリのデータがまだ読み取り可能なうちに外部リソースをクリーンアップできます。
|
||||
|
||||
<Note>
|
||||
インストールフックは [logic function](/l/ja/developers/extend/apps/logic/logic-functions) ランタイムを共有します。つまり、同じハンドラーシグネチャ、同じ環境変数、同じ型付き API クライアントを使用します。ただし、独自の define 関数で宣言され、通常のトリガーモデル(HTTP、cron、データベースイベント)とは別に存在します。
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — ソースファイルを監視し、接続された Twenty サーバーへ変更をライブ同期します。 スキーマが変更されると、型付き API クライアントは自動的に再生成されます。
|
||||
* **`yarn twenty dev:build`** — TypeScript をコンパイルし、esbuild でロジック関数とフロントコンポーネントをバンドルして、マニフェストを生成します。
|
||||
* **プリ/ポストインストールフック** — インストール中に実行されるオプションの関数。 詳細は [Install Hooks](/l/ja/developers/extend/apps/config/install-hooks) を参照してください。
|
||||
* **プリ/ポストインストールおよびアンインストールフック** — インストール中または削除直前に実行されるオプションの関数。 詳細は [Install Hooks](/l/ja/developers/extend/apps/config/install-hooks) を参照してください。
|
||||
|
||||
## 次のステップ
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="設定" icon="screwdriver-wrench" href="/l/ja/developers/extend/apps/config/overview">
|
||||
アプリの識別情報、デフォルトロール、およびインストールフック。
|
||||
アプリの識別情報、デフォルトロール、およびインストールフックとアンインストールフック。
|
||||
</Card>
|
||||
<Card title="データ" icon="database" href="/l/ja/developers/extend/apps/data/overview">
|
||||
オブジェクト、フィールド、および双方向リレーション。
|
||||
|
||||
@@ -149,7 +149,7 @@ yarn twenty apply # show the plan, then apply it
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="設定" icon="screwdriver-wrench" href="/l/ja/developers/extend/apps/config/overview">
|
||||
アプリケーション ID、デフォルトロール、インストールフック、公開アセット。
|
||||
アプリケーション ID、デフォルトロール、インストールおよびアンインストールフック、公開アセット。
|
||||
</Card>
|
||||
<Card title="データ" icon="database" href="/l/ja/developers/extend/apps/data/overview">
|
||||
オブジェクト、フィールド、および双方向リレーション。
|
||||
|
||||
@@ -613,7 +613,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**インストールフック** — pre-install と post-install のハンドラー — はこのランタイムを共有しますが、それぞれ独自の define 関数で宣言され、トリガー設定は受け取りません。 `definePreInstallLogicFunction` と `definePostInstallLogicFunction` については、[インストールフック](/l/ja/developers/extend/apps/config/install-hooks) を参照してください。
|
||||
**インストールフック** — pre-install、post-install、uninstall の各ハンドラー — はこのランタイムを共有しますが、それぞれ独自の define 関数で宣言され、トリガー設定は受け取りません。 `definePreInstallLogicFunction`、`definePostInstallLogicFunction`、`defineUninstallLogicFunction` については、[インストールフック](/l/ja/developers/extend/apps/config/install-hooks) を参照してください。
|
||||
</Note>
|
||||
|
||||
## 型付き API クライアント(`twenty-client-sdk`)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## 関数ログの表示(`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ icon: rocket
|
||||
* **식별 정보** — 범용 식별자, 표시 이름, 설명.
|
||||
* **권한** — 로직 함수와 프런트 컴포넌트가 어떤 역할로 실행되는지.
|
||||
* **변수** *(선택 사항)* — 코드에 환경 변수로 노출되는 키–값 쌍.
|
||||
* **설치 전/후 훅** *(선택 사항)* — [Logic Functions](/l/ko/developers/extend/apps/logic/logic-functions)를 참조하세요.
|
||||
* **설치 전/설치 후/제거 훅** *(선택 사항)* — [Logic Functions](/l/ko/developers/extend/apps/logic/logic-functions)를 참조하세요.
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ export default defineApplication({
|
||||
* `universalIdentifier` 필드는 여러분이 소유하는 변하지 않는 고유 ID입니다. 한 번만 생성하고 이후 동기화 동안에도 변하지 않도록 유지하세요.
|
||||
* `applicationVariables`는 함수와 프런트 컴포넌트의 환경 변수가 됩니다. 로직 함수(서버 사이드)에서는 `process.env.VARIABLE_NAME`으로 사용할 수 있습니다. 프런트 컴포넌트에서는 `twenty-sdk/front-component`의 `getApplicationVariable('VARIABLE_NAME')`을 사용하세요. `isSecret: true`로 표시된 변수는 로직 함수에만 주입됩니다. 프런트 컴포넌트는 비밀이 아닌 변수만 받습니다.
|
||||
* 기본 역할은 [`defineApplicationRole()`](/l/ko/developers/extend/apps/config/roles)로 표시된 역할 파일에서 자동으로 감지되므로, `defineApplication()`에서 이를 참조할 필요가 없습니다.
|
||||
* 설치 전/후 함수는 매니페스트 빌드 중 자동으로 감지됩니다 — `defineApplication()`에서 별도로 참조할 필요가 없습니다.
|
||||
* 설치 전, 설치 후, 제거 함수는 매니페스트 빌드 중 자동으로 감지됩니다 — `defineApplication()`에서 별도로 참조할 필요가 없습니다.
|
||||
* 하위 호환성을 위해 `defaultRoleUniversalIdentifier`를 명시적으로 전달하는 방식도 계속 지원되지만, 이제는 `defineApplicationRole()` 사용을 권장하며 이전 방식은 더 이상 권장되지 않습니다.
|
||||
* `serverVariables`는 인스턴스 범위의 구성 및 비밀(예: API 키)입니다. `applicationVariables`와 달리, 매니페스트에는 값을 선언하지 않으며, 워크스페이스 운영자가 앱 설정에서 값을 채워 넣으면 설정된 이후에만 로직 함수에 주입됩니다.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: 설치 훅
|
||||
description: 설치 전에나 후에 로직을 실행하여 시드 데이터를 추가하고, 레코드를 백업하고, 업그레이드를 검증하세요.
|
||||
description: 설치, 업그레이드 또는 제거 라이프사이클 동안 로직을 실행하여 데이터를 시드하고, 레코드를 백업하고, 업그레이드를 검증하고, 외부 리소스를 정리합니다.
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
설치 훅은 설치 또는 업그레이드 라이프사이클 동안 실행되는 특수한 로직 함수입니다. 이들은 일반 [로직 함수](/l/ko/developers/extend/apps/logic/logic-functions)와 동일한 핸들러 런타임을 공유하고 `InstallPayload`를 받습니다(`{ previousVersion?: string; newVersion: string }` — 새로운 설치에서는 `previousVersion`이 `undefined`임). 하지만 자체 define 함수로 선언되며, 일반 트리거 모델(HTTP, cron, 데이터베이스 이벤트) 외부에서 동작합니다.
|
||||
설치 훅은 설치, 업그레이드 또는 제거 라이프사이클 동안 실행되는 특수한 로직 함수입니다. 이들은 일반 [로직 함수](/l/ko/developers/extend/apps/logic/logic-functions)와 동일한 핸들러 런타임을 공유하지만, 자체 define 함수로 선언되며 일반 트리거 모델(HTTP, cron, 데이터베이스 이벤트) 외부에서 동작합니다. 설치 훅은 `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — 새로 설치하는 경우 `previousVersion`은 `undefined`임)을 받고, 제거 훅은 제거되는 버전을 나타내는 `UninstallPayload` (`{ version?: string }`)을 받습니다.
|
||||
|
||||
각 앱은 **최대 하나의 pre-install** 함수와 **최대 하나의 post-install** 함수만 정의할 수 있습니다. 둘 중 하나가 둘 이상 감지되면 매니페스트 빌드에서 오류가 발생합니다.
|
||||
각 앱은 각 훅(pre-install, post-install, uninstall)을 **최대 하나씩만** 정의할 수 있습니다. 어떤 종류든 둘 이상 감지되면 매니페스트 빌드에서 오류가 발생합니다.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 제거 훅
|
||||
|
||||
`defineUninstallLogicFunction`은 사용자가 앱을 제거할 때 실행되는 훅을 선언합니다. 이 훅은 앱의 메타데이터, 데이터, 코드가 제거되기 **이전**에 실행됩니다. 삭제 마이그레이션이 실행된 후에는 더 이상 실행할 것이 남지 않으므로, 핸들러는 여전히 앱의 오브젝트와 레코드를 쿼리할 수 있습니다. 이를 외부 리소스 정리에 사용하십시오. 예를 들어 API 리소스 프로비저닝 해제, 남은 봇 삭제, 웹훅 해지에 사용할 수 있습니다.
|
||||
|
||||
노트:
|
||||
|
||||
* 이 훅은 최대한 시도(best-effort) 방식으로 동작합니다. 동기적으로 실행되지만, 실패해도 로그에만 기록되고 **제거를 차단하지 않습니다**. 정리 작업 때문에 앱을 제거할 수 없게 만들어서는 안 됩니다.
|
||||
* 이 훅은 제거되는 버전을 나타내는 `UninstallPayload` (`{ version?: string }`)을 받습니다.
|
||||
* 새 설치가 실패하여 롤백될 때는 이 훅이 **실행되지 않습니다**. 앱 설치가 끝까지 완료되지 않았기 때문입니다.
|
||||
* 앱이 제거된 후에는 이 훅을 실행할 수 없으므로, 앱 데이터(예: 레코드에 저장된 봇 ID)에 의존하는 외부 정리 작업은 외부 예약 작업이 아니라 여기에서 수행해야 합니다.
|
||||
* 설치 훅과 마찬가지로, 이 훅은 **개발 모드에서는 실행되지 않습니다**. 대신 수동으로 트리거해야 합니다:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ Twenty 앱의 **구성 레이어(config layer)** 는 앱의 ID, 보유한 권한
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ Twenty 앱의 **구성 레이어(config layer)** 는 앱의 ID, 보유한 권한
|
||||
`defineRole` — 앱의 로직 함수가 무엇을 읽고 쓸 수 있는지 선언합니다.
|
||||
</Card>
|
||||
<Card title="설치 훅" icon="wrench" href="/l/ko/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` 및 `definePostInstallLogicFunction` — 데이터를 백업하고, 기본값을 시드하며, 업그레이드를 검증합니다.
|
||||
`definePreInstallLogicFunction`, `definePostInstallLogicFunction`, 그리고 `defineUninstallLogicFunction` — 데이터를 백업하고, 기본값을 시드하며, 업그레이드를 검증하고, 제거 시 정리를 수행합니다.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ Twenty 앱의 **구성 레이어(config layer)** 는 앱의 ID, 보유한 권한
|
||||
|
||||
* **애플리케이션**이 진입점입니다. 모든 앱에는 정확히 한 번의 `defineApplication()` 호출이 있으며, 이 호출은 하나의 \*\*역할(Role)\*\*을 기본값으로 가리킵니다.
|
||||
* \*\*역할(Role)\*\*은 앱의 로직 함수와 프런트 컴포넌트가 무엇을 읽고 쓸 수 있는지를 제어합니다. 최소 권한 원칙을 따르세요. 코드에 실제로 필요한 권한만 부여하세요.
|
||||
* \*\*설치 훅(Install Hooks)\*\*은 설치나 업그레이드 중에 실행됩니다. 메타데이터 마이그레이션 이전에 실행되는 사전 설치 훅은 위험한 업그레이드를 거부할 수 있고, 마이그레이션 이후에 실행되는 사후 설치 훅은 새 스키마에 맞춰 기본 데이터를 시드할 수 있습니다.
|
||||
* \*\*설치 훅(Install Hooks)\*\*은 설치나 업그레이드 중에 실행됩니다. 메타데이터 마이그레이션 이전에 실행되는 사전 설치 훅은 위험한 업그레이드를 거부할 수 있고, 마이그레이션 이후에 실행되는 사후 설치 훅은 새 스키마에 맞춰 기본 데이터를 시드할 수 있습니다. 제거 훅은 앱이 제거되기 직전에 실행되므로, 앱의 데이터를 still 읽을 수 있는 동안 외부 리소스를 정리할 수 있습니다.
|
||||
|
||||
<Note>
|
||||
설치 훅은 [로직 함수](/l/ko/developers/extend/apps/logic/logic-functions) 런타임을 공유합니다. 동일한 핸들러 시그니처, 동일한 환경 변수, 동일한 타입이 지정된 API 클라이언트를 사용하지만, 자체 define 함수로 선언되고 일반 트리거 모델(HTTP, cron, 데이터베이스 이벤트) 외부에서 동작합니다.
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — 소스 파일을 감시하고 연결된 Twenty 서버로 변경 사항을 실시간 동기화합니다. 스키마가 변경되면 타입이 지정된 API 클라이언트가 자동으로 재생성됩니다.
|
||||
* **`yarn twenty dev:build`** — TypeScript를 컴파일하고, 로직 함수와 프런트 컴포넌트를 esbuild로 번들링하며, 매니페스트를 생성합니다.
|
||||
* **사전/사후 설치 훅** — 설치 중에 실행되는 선택적 함수입니다. 자세한 내용은 [Install Hooks](/l/ko/developers/extend/apps/config/install-hooks)를 참조하세요.
|
||||
* **사전/사후 설치 및 제거 훅** — 설치 중이거나 제거 직전에 실행되는 선택적 함수입니다. 자세한 내용은 [Install Hooks](/l/ko/developers/extend/apps/config/install-hooks)를 참조하세요.
|
||||
|
||||
## 다음 단계
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="설정" icon="screwdriver-wrench" href="/l/ko/developers/extend/apps/config/overview">
|
||||
애플리케이션 식별, 기본 역할, 설치 훅.
|
||||
애플리케이션 식별, 기본 역할, 설치 및 제거 훅.
|
||||
</Card>
|
||||
<Card title="데이터" icon="database" href="/l/ko/developers/extend/apps/data/overview">
|
||||
객체, 필드, 양방향 관계.
|
||||
|
||||
@@ -149,7 +149,7 @@ yarn twenty apply # show the plan, then apply it
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="설정" icon="screwdriver-wrench" href="/l/ko/developers/extend/apps/config/overview">
|
||||
애플리케이션 ID, 기본 역할, 설치 훅, 공개 자산.
|
||||
애플리케이션 ID, 기본 역할, 설치 및 제거 훅, 공개 자산.
|
||||
</Card>
|
||||
<Card title="데이터" icon="database" href="/l/ko/developers/extend/apps/data/overview">
|
||||
객체, 필드, 그리고 양방향 관계.
|
||||
|
||||
@@ -612,7 +612,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**설치 훅** — 사전 설치 및 사후 설치 핸들러 — 는 이 런타임을 공유하지만, 각각의 `define` 함수로 선언되며 트리거 설정을 받지 않습니다. `definePreInstallLogicFunction` 및 `definePostInstallLogicFunction` 에 대해서는 [설치 훅](/l/ko/developers/extend/apps/config/install-hooks)을 참고하세요.
|
||||
**설치 훅** — 사전 설치, 사후 설치 및 제거 핸들러 — 는 이 런타임을 공유하지만, 각각의 `define` 함수로 선언되며 트리거 설정을 받지 않습니다. `definePreInstallLogicFunction`, `definePostInstallLogicFunction`, 및 `defineUninstallLogicFunction` 에 대해서는 [설치 훅](/l/ko/developers/extend/apps/config/install-hooks)을 참고하세요.
|
||||
</Note>
|
||||
|
||||
## 타입이 지정된 API 클라이언트(twenty-client-sdk)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## 함수 로그 보기(`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ Todo app deve ter exatamente uma chamada a `defineApplication`. Ela declara:
|
||||
* **Identidade** — identificador universal, nome de exibição, descrição.
|
||||
* **Permissões** — qual papel é usado pelas suas funções de lógica e pelos componentes de front-end.
|
||||
* **Variáveis** *(opcional)* — pares chave–valor expostos ao seu código como variáveis de ambiente.
|
||||
* **Hooks de pré-instalação/pós-instalação** *(opcional)* — consulte [Funções de lógica](/l/pt/developers/extend/apps/logic/logic-functions).
|
||||
* **Hooks de pré-instalação/pós-instalação/desinstalação** *(opcional)* — consulte [Funções de lógica](/l/pt/developers/extend/apps/logic/logic-functions).
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ Notas:
|
||||
* Os campos `universalIdentifier` são IDs determinísticos que você controla. Gere-os uma vez e mantenha-os estáveis entre sincronizações.
|
||||
* `applicationVariables` tornam-se variáveis de ambiente para suas funções e componentes de front-end. Em funções lógicas (no lado do servidor), elas ficam disponíveis como `process.env.VARIABLE_NAME`. Em componentes de front-end, use `getApplicationVariable('VARIABLE_NAME')` de `twenty-sdk/front-component`. Variáveis marcadas com `isSecret: true` são injetadas apenas em funções lógicas. Componentes de front-end recebem apenas variáveis não secretas.
|
||||
* O papel padrão é detectado automaticamente a partir do arquivo de definição de papel marcado com [`defineApplicationRole()`](/l/pt/developers/extend/apps/config/roles) — você não precisa referenciá-lo em `defineApplication()`.
|
||||
* As funções de pré-instalação e pós-instalação são detectadas automaticamente durante a construção do manifesto — você não precisa referenciá-las em `defineApplication()`.
|
||||
* As funções de pré-instalação, pós-instalação e desinstalação são detectadas automaticamente durante a construção do manifesto — você não precisa referenciá-las em `defineApplication()`.
|
||||
* Passar `defaultRoleUniversalIdentifier` explicitamente ainda é compatível para retrocompatibilidade, mas foi preterido em favor de `defineApplicationRole()`.
|
||||
* `serverVariables` são configurações e segredos com escopo de instância (por exemplo, chaves de API). Ao contrário de `applicationVariables`, eles não declaram nenhum valor no manifesto — o operador do workspace os preenche nas configurações do app, e eles são injetados nas funções de lógica somente depois de definidos.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: Hooks de instalação
|
||||
description: Execute lógica antes ou depois da instalação — para popular dados, fazer backup de registros, validar a atualização.
|
||||
description: Execute lógica durante o ciclo de vida de instalação, atualização ou desinstalação — popule dados iniciais, faça backup de registros, valide a atualização, limpe recursos externos.
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
Hooks de instalação são funções de lógica especiais que são executadas durante o ciclo de vida de instalação ou atualização. Elas compartilham o mesmo runtime de handler que as [logic functions](/l/pt/developers/extend/apps/logic/logic-functions) normais e recebem um `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` é `undefined` em uma instalação nova), mas são declaradas com suas próprias funções de definição e ficam fora do modelo de gatilhos normal (HTTP, cron, eventos de banco de dados).
|
||||
Hooks de instalação são funções de lógica especiais que são executadas durante o ciclo de vida de instalação, atualização ou desinstalação. Elas compartilham o mesmo runtime de handler que as [logic functions](/l/pt/developers/extend/apps/logic/logic-functions) normais, mas são declaradas com suas próprias funções de definição e ficam fora do modelo de gatilhos normal (HTTP, cron, eventos de banco de dados). Hooks de instalação recebem um `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` é `undefined` em uma instalação nova); o hook de desinstalação recebe um `UninstallPayload` (`{ version?: string }` — a versão que está sendo removida).
|
||||
|
||||
Cada aplicativo pode definir no máximo uma função de pré-instalação e no máximo uma função de pós-instalação. A geração do manifesto apresentará erro se mais de uma de cada for detectada.
|
||||
Cada app pode definir **no máximo um** de cada hook (pre-instalação, pós-instalação, desinstalação). A geração do manifesto apresentará erro se mais de um de qualquer tipo for detectado.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Hook de desinstalação
|
||||
|
||||
`defineUninstallLogicFunction` declara um hook que é executado quando um usuário desinstala seu app. Ele é executado **antes** que os metadados, dados e código do app sejam removidos — depois que a migration de exclusão é executada, não sobra nada para executar — portanto, seu handler ainda pode consultar os objetos e registros do app. Use-o para limpar recursos externos: desprovisionar recursos de API, excluir bots remanescentes, revogar webhooks.
|
||||
|
||||
Notas:
|
||||
|
||||
* O hook é de melhor esforço: ele é executado de forma síncrona, mas uma falha é registrada em log e **nunca bloqueia a desinstalação** — a limpeza não deve tornar impossível remover um app.
|
||||
* Ele recebe `UninstallPayload` (`{ version?: string }` — a versão que está sendo removida).
|
||||
* Ele **não** é executado quando uma instalação nova com falha é revertida — o app nunca chegou a ser totalmente instalado.
|
||||
* O hook não pode ser executado depois que o app foi removido, então a limpeza externa que depende de dados do app (por exemplo, IDs de bots armazenados em registros) deve ser feita aqui, não em um job externo agendado.
|
||||
* Assim como os hooks de instalação, ele **não é executado no modo de desenvolvimento** — em vez disso, acione-o manualmente:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ A **camada de configuração** de uma aplicação Twenty é o que descreve a apl
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ A **camada de configuração** de uma aplicação Twenty é o que descreve a apl
|
||||
`defineRole` — declara o que as funções de lógica da sua aplicação podem ler e escrever.
|
||||
</Card>
|
||||
<Card title="Hooks de instalação" icon="wrench" href="/l/pt/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` e `definePostInstallLogicFunction` — criam cópias de segurança dos dados, inicializam valores predefinidos, validam atualizações.
|
||||
`definePreInstallLogicFunction`, `definePostInstallLogicFunction` e `defineUninstallLogicFunction` — criam cópias de segurança dos dados, inicializam valores predefinidos, validam atualizações e fazem a limpeza na remoção.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ A **camada de configuração** de uma aplicação Twenty é o que descreve a apl
|
||||
|
||||
* A **Aplicação** é o ponto de entrada. Cada aplicação tem exatamente uma chamada `defineApplication()`, e esta aponta para uma **Função** como predefinida.
|
||||
* A **Função** controla o que as funções de lógica e os componentes de front-end da aplicação podem ler e escrever. Siga o princípio do menor privilégio: conceda apenas as permissões de que o seu código realmente necessita.
|
||||
* Os **Hooks de instalação** são executados durante a instalação ou atualização — a pré-instalação antes da migração de metadados (para que possa recusar uma atualização arriscada) e a pós-instalação após a migração (para que possa inicializar dados predefinidos com base no novo esquema).
|
||||
* Os **Hooks de instalação** são executados durante a instalação ou atualização — a pré-instalação antes da migração de metadados (para que possa recusar uma atualização arriscada) e a pós-instalação após a migração (para que possa inicializar dados predefinidos com base no novo esquema). O hook de desinstalação é executado imediatamente antes de o app ser removido, para que ele possa limpar recursos externos enquanto os dados do app ainda são legíveis.
|
||||
|
||||
<Note>
|
||||
Os hooks de instalação partilham o ambiente de execução de [função de lógica](/l/pt/developers/extend/apps/logic/logic-functions) — a mesma assinatura de handler, as mesmas variáveis de ambiente, o mesmo cliente de API tipado — mas são declarados com as suas próprias funções "define" e vivem fora do modelo de disparo normal (HTTP, cron, eventos de base de dados).
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — observa seus arquivos-fonte e sincroniza ao vivo as alterações com um servidor Twenty conectado. O cliente de API tipado é regenerado automaticamente quando o esquema muda.
|
||||
* **`yarn twenty dev:build`** — compila TypeScript, empacota funções de lógica e componentes de front-end com o esbuild e produz um manifesto.
|
||||
* **Hooks de pré/pós-instalação** — funções opcionais que são executadas durante a instalação. Veja [Hooks de instalação](/l/pt/developers/extend/apps/config/install-hooks) para detalhes.
|
||||
* **Hooks de pré/pós-instalação e desinstalação** — funções opcionais que são executadas durante a instalação ou logo antes da remoção. Veja [Hooks de instalação](/l/pt/developers/extend/apps/config/install-hooks) para detalhes.
|
||||
|
||||
## Próximos passos
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Configuração" icon="screwdriver-wrench" href="/l/pt/developers/extend/apps/config/overview">
|
||||
Identidade da aplicação, função padrão e hooks de instalação.
|
||||
Identidade da aplicação, função padrão e hooks de instalação e desinstalação.
|
||||
</Card>
|
||||
<Card title="Dados" icon="database" href="/l/pt/developers/extend/apps/data/overview">
|
||||
Objetos, campos e relações bidirecionais.
|
||||
|
||||
@@ -149,7 +149,7 @@ Referência completa: [Conceitos](/l/pt/developers/extend/apps/getting-started/c
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Configuração" icon="screwdriver-wrench" href="/l/pt/developers/extend/apps/config/overview">
|
||||
Identidade do aplicativo, função padrão, hooks de instalação, recursos públicos.
|
||||
Identidade do aplicativo, função padrão, hooks de instalação e desinstalação, recursos públicos.
|
||||
</Card>
|
||||
<Card title="Data" icon="database" href="/l/pt/developers/extend/apps/data/overview">
|
||||
Objetos, campos e relações bidirecionais.
|
||||
|
||||
@@ -612,7 +612,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**Hooks de instalação** — manipuladores de pré-instalação e pós-instalação — compartilham esse ambiente de execução, mas são declarados com suas próprias funções de definição e não usam configurações de gatilho. Veja [Hooks de instalação](/l/pt/developers/extend/apps/config/install-hooks) para `definePreInstallLogicFunction` e `definePostInstallLogicFunction`.
|
||||
**Hooks de instalação** — manipuladores de pré-instalação, pós-instalação e desinstalação — compartilham esse ambiente de execução, mas são declarados com suas próprias funções de definição e não usam configurações de gatilho. Veja [Hooks de instalação](/l/pt/developers/extend/apps/config/install-hooks) para `definePreInstallLogicFunction`, `definePostInstallLogicFunction` e `defineUninstallLogicFunction`.
|
||||
</Note>
|
||||
|
||||
## Clientes de API tipados (twenty-client-sdk)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## Visualizando logs de funções (`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ Fiecare aplicație trebuie să aibă exact un apel `defineApplication`. Acesta d
|
||||
* **Identitate** — identificator universal, nume de afișare, descriere.
|
||||
* **Permisiuni** — sub ce rol rulează funcțiile logice și componentele front-end ale acesteia.
|
||||
* **Variabile** *(opțional)* — perechi cheie–valoare expuse codului dvs. ca variabile de mediu.
|
||||
* **Hook-uri de pre-instalare / post-instalare** *(opțional)* — vedeți [Funcții logice](/l/ro/developers/extend/apps/logic/logic-functions).
|
||||
* **Hook-uri de pre-instalare / post-instalare / dezinstalare** *(opțional)* — vedeți [Funcții logice](/l/ro/developers/extend/apps/logic/logic-functions).
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ Notițe:
|
||||
* Câmpurile `universalIdentifier` sunt ID-uri deterministe pe care le dețineți. Generați-le o singură dată și mențineți-le stabile între sincronizări.
|
||||
* `applicationVariables` devin variabile de mediu pentru funcțiile și componentele front-end. În funcțiile de logică (server-side), acestea sunt disponibile ca `process.env.VARIABLE_NAME`. În componentele front-end, folosește `getApplicationVariable('VARIABLE_NAME')` din `twenty-sdk/front-component`. Variabilele marcate cu `isSecret: true` sunt injectate doar în funcțiile de logică. Componentele front-end primesc doar variabile non-secrete.
|
||||
* Rolul implicit este detectat automat din fișierul de rol marcat cu [`defineApplicationRole()`](/l/ro/developers/extend/apps/config/roles) — nu este necesar să faci referire la el în `defineApplication()`.
|
||||
* Funcțiile de pre-instalare și post-instalare sunt detectate automat în timpul construirii manifestului — nu trebuie să le referiți în `defineApplication()`.
|
||||
* Funcțiile de pre-instalare, post-instalare și dezinstalare sunt detectate automat în timpul construirii manifestului — nu este nevoie să faceți referire la ele în `defineApplication()`.
|
||||
* Transmiterea explicită a `defaultRoleUniversalIdentifier` este în continuare acceptată pentru compatibilitate retroactivă, dar este considerată învechită în favoarea `defineApplicationRole()`.
|
||||
* `serverVariables` sunt configurări și secrete la nivel de instanță (de ex. chei API). Spre deosebire de `applicationVariables`, ele nu declară nicio valoare în manifest — operatorul spațiului de lucru le completează din setările aplicației și sunt injectate în funcțiile de logică doar după ce au fost setate.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: Hook-uri de instalare
|
||||
description: Rulați logică înainte sau după instalare — pentru a popula cu date inițiale, a face copii de rezervă ale înregistrărilor, a valida actualizarea.
|
||||
description: Rulați logică în timpul ciclului de viață de instalare, actualizare sau dezinstalare — populați date, faceți backup pentru înregistrări, validați actualizarea, curățați resursele externe.
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
Hook-urile de instalare sunt funcții logice speciale care rulează în timpul ciclului de viață al instalării sau actualizării. Acestea folosesc același runtime de handler ca și [funcțiile logice](/l/ro/developers/extend/apps/logic/logic-functions) obișnuite și primesc un `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` este `undefined` la o instalare nouă), dar sunt declarate cu propriile lor funcții de definire și există în afara modelului obișnuit de declanșatori (HTTP, cron, evenimente de bază de date).
|
||||
Hook-urile de instalare sunt funcții logice speciale care rulează în timpul ciclului de viață de instalare, actualizare sau dezinstalare. Acestea folosesc același runtime de handler ca și [funcțiile logice](/l/ro/developers/extend/apps/logic/logic-functions) obișnuite, dar sunt declarate cu propriile lor funcții de definire și există în afara modelului obișnuit de declanșatori (HTTP, cron, evenimente de bază de date). Hook-urile de instalare primesc un `InstallPayload` (`{ previousVersion?: string; newVersion: string }` — `previousVersion` este `undefined` la o instalare nouă); hook-ul de dezinstalare primește un `UninstallPayload` (`{ version?: string }` — versiunea care este eliminată).
|
||||
|
||||
Fiecare aplicație poate defini **cel mult o funcție de pre-instalare** și **cel mult o funcție de post-instalare**. Construirea manifestului va genera o eroare dacă se detectează mai mult de una din oricare dintre ele.
|
||||
Fiecare aplicație poate defini **cel mult unul** din fiecare hook (pre-instalare, post-instalare, dezinstalare). Construirea manifestului va genera o eroare dacă se detectează mai mult de unul de orice tip.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Hook de dezinstalare
|
||||
|
||||
`defineUninstallLogicFunction` declară un hook care rulează atunci când un utilizator dezinstalează aplicația ta. Acesta este executat **înainte** ca metadatele, datele și codul aplicației să fie eliminate — odată ce migrarea de ștergere rulează, nu mai rămâne nimic de executat — astfel încât handler-ul tău poate încă interoga obiectele și înregistrările aplicației. Folosește-l pentru curățarea resurselor externe: deprovisionarea resurselor API, ștergerea boților rămași, revocarea webhook-urilor.
|
||||
|
||||
Notițe:
|
||||
|
||||
* Hook-ul funcționează după principiul „best-effort“: rulează sincron, dar o eroare este înregistrată și **nu blochează niciodată dezinstalarea** — curățarea nu trebuie să facă imposibilă eliminarea unei aplicații.
|
||||
* Acesta primește `UninstallPayload` (`{ version?: string }` — versiunea care este eliminată).
|
||||
* Nu rulează atunci când o instalare nouă eșuată este anulată — aplicația nu a terminat niciodată instalarea.
|
||||
* Hook-ul nu poate rula după ce aplicația a dispărut, astfel încât curățarea externă care depinde de datele aplicației (de ex. ID-uri de boți stocate în înregistrări) trebuie făcută aici, nu într-un job programat extern.
|
||||
* La fel ca hook-urile de instalare, **nu este executat în modul de dezvoltare (dev mode)** — declanșează-l manual în schimb:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ icon: screwdriver-wrench
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ icon: screwdriver-wrench
|
||||
`defineRole` — declară ce pot citi și scrie funcțiile de logică ale aplicației dvs.
|
||||
</Card>
|
||||
<Card title="Hook-uri de instalare" icon="wrench" href="/l/ro/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` și `definePostInstallLogicFunction` — fac backup la date, introduc valori implicite, validează actualizările.
|
||||
`definePreInstallLogicFunction`, `definePostInstallLogicFunction` și `defineUninstallLogicFunction` — fac backup la date, introduc valori implicite, validează actualizările și curăță la eliminare.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ icon: screwdriver-wrench
|
||||
|
||||
* **Aplicația** este punctul de intrare. Fiecare aplicație are exact un apel `defineApplication()`, iar acesta indică un singur **Rol** ca implicit.
|
||||
* **Rolul** controlează ce pot citi și scrie funcțiile de logică și componentele front-end ale aplicației. Respectați principiul celui mai mic privilegiu: acordați doar permisiunile de care codul dvs. are cu adevărat nevoie.
|
||||
* **Hook-urile de instalare** rulează în timpul instalării sau actualizării — pre-install înainte de migrarea metadatelor (astfel încât să poată refuza o actualizare riscantă), post-install după migrare (astfel încât să poată introduce date implicite în noua schemă).
|
||||
* **Hook-urile de instalare** rulează în timpul instalării sau actualizării — pre-install înainte de migrarea metadatelor (astfel încât să poată refuza o actualizare riscantă), post-install după migrare (astfel încât să poată introduce date implicite în noua schemă). Hook-ul de dezinstalare rulează chiar înainte ca aplicația să fie eliminată, astfel încât poate curăța resursele externe cât timp datele aplicației sunt încă lizibile.
|
||||
|
||||
<Note>
|
||||
Hook-urile de instalare împart același runtime cu [funcțiile de logică](/l/ro/developers/extend/apps/logic/logic-functions) — aceeași semnătură a handlerului, aceleași variabile de mediu, același client API tipizat — dar sunt declarate cu propriile lor funcții `define` și există în afara modelului obișnuit de declanșare (HTTP, cron, evenimente de bază de date).
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — monitorizează fișierele sursă și sincronizează în timp real modificările către un server Twenty conectat. Clientul API tipizat este regenerat automat atunci când schema se schimbă.
|
||||
* **`yarn twenty dev:build`** — compilează TypeScript, împachetează funcțiile logice și componentele front-end cu esbuild și produce un manifest.
|
||||
* **Hook-uri pre/post-instalare** — funcții opționale care rulează în timpul instalării. Vezi [Install Hooks](/l/ro/developers/extend/apps/config/install-hooks) pentru detalii.
|
||||
* **Hook-uri pre/post-instalare și dezinstalare** — funcții opționale care rulează în timpul instalării sau chiar înainte de eliminare. Vezi [Install Hooks](/l/ro/developers/extend/apps/config/install-hooks) pentru detalii.
|
||||
|
||||
## Pașii următori
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Configurare" icon="screwdriver-wrench" href="/l/ro/developers/extend/apps/config/overview">
|
||||
Identitatea aplicației, rolul implicit și hook-urile de instalare.
|
||||
Identitatea aplicației, rolul implicit și hook-urile de instalare și dezinstalare.
|
||||
</Card>
|
||||
<Card title="Date" icon="database" href="/l/ro/developers/extend/apps/data/overview">
|
||||
Obiecte, câmpuri și relații bidirecționale.
|
||||
|
||||
@@ -149,7 +149,7 @@ Referință completă: [Concepte](/l/ro/developers/extend/apps/getting-started/c
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Configurare" icon="screwdriver-wrench" href="/l/ro/developers/extend/apps/config/overview">
|
||||
Identitatea aplicației, rolul implicit, hook-urile de instalare, resursele publice.
|
||||
Identitatea aplicației, rolul implicit, hook-urile de instalare și dezinstalare, resursele publice.
|
||||
</Card>
|
||||
<Card title="Date" icon="database" href="/l/ro/developers/extend/apps/data/overview">
|
||||
Obiecte, câmpuri și relații bidirecționale.
|
||||
|
||||
@@ -613,7 +613,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**Hook-uri de instalare** — handleri pre-instalare și post-instalare — partajează acest runtime, dar sunt declarați cu propriile lor funcții `define` și nu folosesc setări de declanșare. Consultați [Hook-uri de instalare](/l/ro/developers/extend/apps/config/install-hooks) pentru `definePreInstallLogicFunction` și `definePostInstallLogicFunction`.
|
||||
**Hook-uri de instalare** — handleri pre-instalare, post-instalare și dezinstalare — partajează acest runtime, dar sunt declarați cu propriile lor funcții `define` și nu folosesc setări de declanșare. Consultați [Hook-uri de instalare](/l/ro/developers/extend/apps/config/install-hooks) pentru `definePreInstallLogicFunction`, `definePostInstallLogicFunction` și `defineUninstallLogicFunction`.
|
||||
</Note>
|
||||
|
||||
## Clienți API tipizați (twenty-client-sdk)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## Vizualizarea jurnalelor funcțiilor (`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ Her uygulamanın, tam olarak bir adet `defineApplication` çağrısı olması ge
|
||||
* **Kimlik** — evrensel tanımlayıcı, görünen ad, açıklama.
|
||||
* **İzinler** — mantık fonksiyonlarının ve ön uç bileşenlerinin hangi rol altında çalıştığı.
|
||||
* **Değişkenler** *(isteğe bağlı)* — kodunuza ortam değişkenleri olarak sunulan anahtar–değer çiftleri.
|
||||
* **Kurulum öncesi / kurulum sonrası kancalar** *(isteğe bağlı)* — bkz. [Mantık Fonksiyonları](/l/tr/developers/extend/apps/logic/logic-functions).
|
||||
* **Kurulum öncesi / kurulum sonrası / kaldırma kancaları** *(isteğe bağlı)* — bkz. [Mantık Fonksiyonları](/l/tr/developers/extend/apps/logic/logic-functions).
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ Notlar:
|
||||
* `universalIdentifier` alanları, size ait deterministik kimliklerdir. Bunları bir kez oluşturun ve senkronizasyonlar boyunca kararlı tutun.
|
||||
* `applicationVariables`, fonksiyonlarınız ve ön bileşenleriniz için ortam değişkenlerine dönüşür. Mantık fonksiyonlarında (sunucu tarafında), `process.env.VARIABLE_NAME` olarak kullanılabilirler. Ön bileşenlerde, `twenty-sdk/front-component` içindeki `getApplicationVariable('VARIABLE_NAME')` fonksiyonunu kullanın. `isSecret: true` ile işaretlenen değişkenler yalnızca mantık fonksiyonlarına enjekte edilir. Ön bileşenler yalnızca gizli olmayan değişkenleri alır.
|
||||
* Varsayılan rol, [`defineApplicationRole()`](/l/tr/developers/extend/apps/config/roles) ile işaretlenmiş rol dosyasından otomatik olarak algılanır — onu `defineApplication()` içinden belirtmenize gerek yoktur.
|
||||
* Kurulum öncesi ve kurulum sonrası fonksiyonlar manifest derlemesi sırasında otomatik olarak algılanır — bunlara `defineApplication()` içinde referans vermeniz gerekmez.
|
||||
* Kurulum öncesi, kurulum sonrası ve kaldırma fonksiyonları manifest derlemesi sırasında otomatik olarak algılanır — bunlara `defineApplication()` içinde referans vermeniz gerekmez.
|
||||
* Geriye dönük uyumluluk için `defaultRoleUniversalIdentifier` değerini açıkça geçmek hâlâ desteklenmektedir, ancak `defineApplicationRole()` lehine kullanımdan kaldırılmıştır.
|
||||
* `serverVariables`, API anahtarları gibi örnek düzeyindeki yapılandırmalar ve gizli bilgilerdir. `applicationVariables`'ın aksine, manifest içinde herhangi bir değer belirtmezler — çalışma alanı operatörü bunları uygulamanın ayarlarından doldurur ve yalnızca ayarlandıklarında mantık fonksiyonlarına enjekte edilirler.
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: Kurulum Kancaları
|
||||
description: Kurulumdan önce veya sonra mantığı çalıştırın — veri tohumlayın, kayıtları yedekleyin, yükseltmeyi doğrulayın.
|
||||
description: Kurulum, yükseltme veya kaldırma yaşam döngüsü sırasında mantık çalıştırın — başlangıç verilerini yükleyin, kayıtları yedekleyin, yükseltmeyi doğrulayın, harici kaynakları temizleyin.
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
Kurulum kancaları, kurulum veya yükseltme yaşam döngüsü sırasında çalışan özel mantık işlevleridir. Bunlar, normal [mantık işlevleri](/l/tr/developers/extend/apps/logic/logic-functions) ile aynı işleyici çalışma zamanını paylaşır ve bir `InstallPayload` alırlar (`{ previousVersion?: string; newVersion: string }` — yeni bir kurulumda `previousVersion` `undefined` olur), ancak kendi tanımlama işlevleriyle bildirilirler ve normal tetikleyici modelinin (HTTP, cron, veritabanı olayları) dışında yer alırlar.
|
||||
Kurulum kancaları, kurulum, yükseltme veya kaldırma yaşam döngüsü sırasında çalışan özel mantık işlevleridir. Bunlar, normal [mantık işlevleri](/l/tr/developers/extend/apps/logic/logic-functions) ile aynı işleyici çalışma zamanını paylaşır, ancak kendi tanımlama işlevleriyle bildirilirler ve normal tetikleyici modelinin (HTTP, cron, veritabanı olayları) dışında yaşarlar. Kurulum kancaları bir `InstallPayload` alır (`{ previousVersion?: string; newVersion: string }` — yeni bir kurulumda `previousVersion`, `undefined` olur); kaldırma kancası ise bir `UninstallPayload` alır (`{ version?: string }` — kaldırılan sürüm).
|
||||
|
||||
Her uygulama **en fazla bir kurulum öncesi** ve **en fazla bir kurulum sonrası** işlev tanımlayabilir. Her ikisinden de birden fazla tespit edilirse manifest oluşturma hataya düşer.
|
||||
Her uygulama, her bir kanca türünden (kurulum öncesi, kurulum sonrası, kaldırma) **en fazla bir tane** tanımlayabilir. Her türden birden fazla tespit edilirse manifest derlemesi hata verir.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Kaldırma kancası
|
||||
|
||||
`defineUninstallLogicFunction`, bir kullanıcı uygulamanızı kaldırdığında çalışan bir kancayı bildirir. Bu kanca, uygulamanın üst verileri, verileri ve kodu kaldırılmadan **önce** çalışır — silme geçişi (migration) çalıştıktan sonra çalıştırılacak hiçbir şey kalmaz — bu nedenle işleyiciniz uygulamanın nesnelerini ve kayıtlarını hâlâ sorgulayabilir. Bunu harici kaynakların temizliği için kullanın: API kaynaklarının tahsisini geri alın, kalan botları silin, web kancalarını (webhook) iptal edin.
|
||||
|
||||
Notlar:
|
||||
|
||||
* Kanca, en iyi gayret esasına göre çalışır: senkron olarak çalışır, ancak bir hata günlüğe kaydedilir ve **kaldırmayı asla engellemez** — temizleme, bir uygulamanın kaldırılamaz hale gelmesine neden olmamalıdır.
|
||||
* Kaldırma kancası, `UninstallPayload` alır (`{ version?: string }` — kaldırılan sürüm).
|
||||
* Başarısız olan yeni bir kurulum geri alındığında çalışmaz — uygulama kurulumunu hiçbir zaman tamamlamamıştır.
|
||||
* Kanca, uygulama kaldırıldıktan sonra çalışamaz; bu nedenle, uygulama verilerine bağlı olan harici temizlik (örneğin kayıtlarda saklanan bot kimlikleri) harici zamanlanmış bir işte değil, burada yapılmalıdır.
|
||||
* Kurulum kancalarında olduğu gibi, bu kanca da **geliştirme modunda çalıştırılmaz** — bunun yerine manuel olarak tetikleyin:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ Bir Twenty uygulamasının **config katmanı**, uygulamayı *platforma tanımlar
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ Bir Twenty uygulamasının **config katmanı**, uygulamayı *platforma tanımlar
|
||||
`defineRole` — uygulamanızın mantık fonksiyonlarının neleri okuyup yazabildiğini tanımlayın.
|
||||
</Card>
|
||||
<Card title="Kurulum Kancaları" icon="wrench" href="/l/tr/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` ve `definePostInstallLogicFunction` — verileri yedekleyin, varsayılanları tohumlayın, yükseltmeleri doğrulayın.
|
||||
`definePreInstallLogicFunction`, `definePostInstallLogicFunction` ve `defineUninstallLogicFunction` — verileri yedekleyin, varsayılanları tohumlayın, yükseltmeleri doğrulayın, kaldırma sırasında temizleyin.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ Bir Twenty uygulamasının **config katmanı**, uygulamayı *platforma tanımlar
|
||||
|
||||
* **Application** giriş noktasıdır. Her uygulamada tam olarak bir `defineApplication()` çağrısı vardır ve bu çağrı varsayılan olarak bir **Rol**e işaret eder.
|
||||
* **Rol**, uygulamanın mantık fonksiyonlarının ve ön bileşenlerinin neleri okuyup yazabildiğini kontrol eder. En az ayrıcalık ilkesini izleyin: kodunuzun gerçekten ihtiyaç duyduğu izinleri verin.
|
||||
* **Install Hooks**, kurulum veya yükseltme sırasında çalışır — ön kurulum, metadata migrasyonundan önce (böylece riskli bir yükseltmeyi reddedebilir), son kurulum migrasyondan sonra (böylece yeni şemaya karşı varsayılan verileri tohumlayabilir).
|
||||
* **Install Hooks**, kurulum veya yükseltme sırasında çalışır — ön kurulum, metadata migrasyonundan önce (böylece riskli bir yükseltmeyi reddedebilir), son kurulum migrasyondan sonra (böylece yeni şemaya karşı varsayılan verileri tohumlayabilir). Kaldırma kancası, uygulama kaldırılmadan hemen önce çalışır, böylece uygulamanın verileri hâlâ okunabilirken harici kaynakları temizleyebilir.
|
||||
|
||||
<Note>
|
||||
Kurulum kancaları, [mantık fonksiyonu](/l/tr/developers/extend/apps/logic/logic-functions) çalışma zamanını paylaşır — aynı handler imzası, aynı ortam değişkenleri, aynı türlendirilmiş API istemcisi — ancak kendi define fonksiyonlarıyla deklare edilir ve normal tetikleyici modelinin (HTTP, cron, veritabanı olayları) dışında yaşarlar.
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — kaynak dosyalarınızı izler ve bağlı bir Twenty sunucusuna değişiklikleri canlı olarak senkronize eder. Şema değiştiğinde tipli API istemcisi otomatik olarak yeniden oluşturulur.
|
||||
* **`yarn twenty dev:build`** — TypeScript'i derler, mantık işlevlerini ve ön uç bileşenlerini esbuild ile paketler ve bir manifest üretir.
|
||||
* **Kurulum öncesi/sonrası kancaları** — kurulum sırasında çalışan isteğe bağlı işlevler. Ayrıntılar için [Kurulum Kancaları](/l/tr/developers/extend/apps/config/install-hooks) bölümüne bakın.
|
||||
* **Kurulum öncesi/sonrası ve kaldırma öncesi/sonrası kancalar** — kurulum sırasında veya kaldırılmadan hemen önce çalışan isteğe bağlı işlevler. Ayrıntılar için [Kurulum Kancaları](/l/tr/developers/extend/apps/config/install-hooks) bölümüne bakın.
|
||||
|
||||
## Sonraki adımlar
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Yapılandırma" icon="screwdriver-wrench" href="/l/tr/developers/extend/apps/config/overview">
|
||||
Uygulama kimliği, varsayılan rol ve kurulum kancaları.
|
||||
Uygulama kimliği, varsayılan rol ve kurulum ile kaldırma kancaları.
|
||||
</Card>
|
||||
<Card title="Veri" icon="database" href="/l/tr/developers/extend/apps/data/overview">
|
||||
Nesneler, alanlar ve çift yönlü ilişkiler.
|
||||
|
||||
@@ -149,7 +149,7 @@ Tam başvuru: [Kavramlar](/l/tr/developers/extend/apps/getting-started/concepts)
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Yapılandırma" icon="screwdriver-wrench" href="/l/tr/developers/extend/apps/config/overview">
|
||||
Uygulama kimliği, varsayılan rol, kurulum kancaları, genel varlıklar.
|
||||
Uygulama kimliği, varsayılan rol, kurulum ve kaldırma kancaları, genel varlıklar.
|
||||
</Card>
|
||||
<Card title="Veri" icon="database" href="/l/tr/developers/extend/apps/data/overview">
|
||||
Nesneler, alanlar ve çift yönlü ilişkiler.
|
||||
|
||||
@@ -613,7 +613,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**Yükleme kancaları** — ön yükleme ve yükleme sonrası işleyiciler — bu çalışma zamanını paylaşır ancak kendi tanımlama işlevleriyle bildirilir ve tetikleyici ayarlarını almaz. `definePreInstallLogicFunction` ve `definePostInstallLogicFunction` için [Yükleme Kancaları](/l/tr/developers/extend/apps/config/install-hooks) bölümüne bakın.
|
||||
**Yükleme kancaları** — ön yükleme, yükleme sonrası ve kaldırma işleyicileri — bu çalışma zamanını paylaşır ancak kendi tanımlama işlevleriyle bildirilir ve tetikleyici ayarlarını almaz. `definePreInstallLogicFunction`, `definePostInstallLogicFunction` ve `defineUninstallLogicFunction` için [Yükleme Kancaları](/l/tr/developers/extend/apps/config/install-hooks) bölümüne bakın.
|
||||
</Note>
|
||||
|
||||
## Tipli API istemcileri (twenty-client-sdk)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## Fonksiyon günlüklerini görüntüleme (`yarn twenty dev:function:logs`)
|
||||
|
||||
@@ -9,7 +9,7 @@ icon: rocket
|
||||
* **应用的身份** — 通用标识符、显示名称、描述。
|
||||
* **权限** — 其逻辑函数和前端组件在何种角色下运行。
|
||||
* **变量**(可选)— 以环境变量形式暴露给代码的键值对。
|
||||
* **安装前/安装后函数**(可选)— 参见 [逻辑函数](/l/zh/developers/extend/apps/logic/logic-functions)。
|
||||
* **安装前/安装后/卸载函数**(可选)— 参见 [逻辑函数](/l/zh/developers/extend/apps/logic/logic-functions)。
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -34,7 +34,7 @@ export default defineApplication({
|
||||
* `universalIdentifier` 字段是你拥有的确定性 ID。 只需生成一次,并在多次同步过程中保持稳定不变。
|
||||
* `applicationVariables` 会变成你的函数和前端组件可用的环境变量。 在逻辑函数(服务端)中,可以通过 `process.env.VARIABLE_NAME` 使用它们。 在前端组件中,使用 `twenty-sdk/front-component` 中的 `getApplicationVariable('VARIABLE_NAME')`。 标记为 `isSecret: true` 的变量只会注入到逻辑函数中。 前端组件只会接收非机密变量。
|
||||
* 默认角色会根据使用 [`defineApplicationRole()`](/l/zh/developers/extend/apps/config/roles) 标记的角色文件自动检测——你不需要在 `defineApplication()` 中引用它。
|
||||
* 在构建清单时会自动检测安装前/安装后函数——无需在 `defineApplication()` 中引用它们。
|
||||
* 在构建清单时会自动检测安装前、安装后和卸载函数——无需在 `defineApplication()` 中引用它们。
|
||||
* 显式传递 `defaultRoleUniversalIdentifier` 仍然受支持以保持向后兼容性,但已弃用,推荐改用 `defineApplicationRole()`。
|
||||
* `serverVariables` 是实例级的配置和机密信息(例如 API 密钥)。 与 `applicationVariables` 不同,它们不会在 manifest 中声明具体值——工作区运维人员会在应用设置中填写这些值,并且它们只有在被设置后才会被注入到逻辑函数中。
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: 安装钩子
|
||||
description: 在安装之前或之后运行逻辑——预置数据、备份记录、验证升级。
|
||||
description: 在安装、升级或卸载生命周期中运行逻辑——预置数据、备份记录、验证升级、清理外部资源。
|
||||
icon: wrench
|
||||
---
|
||||
|
||||
安装钩子是在安装或升级生命周期期间运行的特殊逻辑函数。 它们与常规的[逻辑函数](/l/zh/developers/extend/apps/logic/logic-functions)共享相同的处理程序运行时,并接收一个 `InstallPayload`(`{ previousVersion?: string; newVersion: string }`——在全新安装时 `previousVersion` 为 `undefined`),但它们使用自己的 define 函数声明,并且存在于普通触发模型(HTTP、cron、数据库事件)之外。
|
||||
安装钩子是在安装、升级或卸载生命周期期间运行的特殊逻辑函数。 它们与常规的[逻辑函数](/l/zh/developers/extend/apps/logic/logic-functions)共享相同的处理程序运行时,但使用自己的定义函数声明,并且存在于普通触发模型(HTTP、cron、数据库事件)之外。 安装钩子接收一个 `InstallPayload`(`{ previousVersion?: string; newVersion: string }`——在全新安装时 `previousVersion` 为 `undefined`);卸载钩子接收一个 `UninstallPayload`(`{ version?: string }`——要被移除的版本)。
|
||||
|
||||
每个应用**最多只能定义一个安装前函数**和**最多一个安装后函数**。 如果检测到任一类型多于一个,清单构建将报错。
|
||||
每个应用每种钩子(预安装、后安装、卸载)最多只能定义一个。 如果检测到任一类型多于一个,清单构建将报错。
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -142,3 +142,47 @@ export default definePreInstallLogicFunction({
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 卸载钩子
|
||||
|
||||
`defineUninstallLogicFunction` 声明一个在用户卸载你的应用时运行的钩子。 它在应用的元数据、数据和代码被移除之前执行——一旦删除迁移运行完成,就不再有任何内容可供执行——因此你的处理程序仍然可以查询应用的对象和记录。 将其用于清理外部资源:取消预置 API 资源、删除剩余的机器人、撤销网络钩子。
|
||||
|
||||
备注:
|
||||
|
||||
* 该钩子是尽力执行:它同步运行,但失败会被记录,并且**绝不会阻止卸载**——清理操作绝不能导致应用无法被移除。
|
||||
* 它接收 `UninstallPayload`(`{ version?: string }`——要被移除的版本)。
|
||||
* 在回滚失败的全新安装时,它**不会**运行——该应用从未完成安装。
|
||||
* 钩子无法在应用被删除后运行,因此依赖应用数据的外部清理(例如存储在记录中的机器人 ID)应放在这里,而不是放在外部计划任务中。
|
||||
* 与安装钩子类似,它在开发模式下**不会执行**——请改为手动触发:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
```ts src/logic-functions/uninstall.ts
|
||||
import { defineUninstallLogicFunction, type UninstallPayload } from 'twenty-sdk/define';
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
|
||||
const handler = async (_payload: UninstallPayload): Promise<void> => {
|
||||
const client = new CoreApiClient();
|
||||
const { meetingBots } = await client.query({
|
||||
meetingBots: { edges: { node: { id: true, externalBotId: true } } },
|
||||
});
|
||||
|
||||
// Delete the provider-side bots so nothing keeps recording after uninstall.
|
||||
for (const { node } of meetingBots.edges) {
|
||||
await fetch(`https://api.recorder.example/bots/${node.externalBotId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${process.env.RECORDER_API_KEY}` },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default defineUninstallLogicFunction({
|
||||
universalIdentifier: 'b2c3d4e5-6789-01bc-def0-234567890abc',
|
||||
name: 'uninstall',
|
||||
description: 'Deletes remaining recorder bots when the app is uninstalled.',
|
||||
timeoutSeconds: 300,
|
||||
handler,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -23,6 +23,11 @@ Twenty 应用的 **配置层(config layer)** 用来向 *平台* 描述应用
|
||||
└──────────────────────────────────┘
|
||||
┌──────────────────────────────────┐
|
||||
│ Post-install hook │ after metadata migration
|
||||
└──────────────────────────────────┘
|
||||
│
|
||||
▼ (at uninstall time)
|
||||
┌──────────────────────────────────┐
|
||||
│ Uninstall hook │ before app removal
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -36,7 +41,7 @@ Twenty 应用的 **配置层(config layer)** 用来向 *平台* 描述应用
|
||||
`defineRole` —— 声明应用的逻辑函数可以读取和写入什么。
|
||||
</Card>
|
||||
<Card title="安装钩子" icon="wrench" href="/l/zh/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` 和 `definePostInstallLogicFunction` —— 备份数据、写入默认值、验证升级。
|
||||
`definePreInstallLogicFunction`、`definePostInstallLogicFunction` 和 `defineUninstallLogicFunction` —— 备份数据、写入默认值、验证升级、在卸载时清理。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -44,7 +49,7 @@ Twenty 应用的 **配置层(config layer)** 用来向 *平台* 描述应用
|
||||
|
||||
* **Application** 是入口点。 每个应用都有且仅有一次 `defineApplication()` 调用,并将一个 **Role** 作为其默认角色。
|
||||
* **Role** 控制应用的逻辑函数和前端组件可以读取和写入什么。 遵循最小权限原则:只授予代码实际需要的权限。
|
||||
* **Install Hooks(安装钩子)** 在安装或升级过程中运行——预安装钩子在元数据迁移之前运行(因此可以拒绝存在风险的升级),后安装钩子在迁移之后运行(因此可以根据新模式写入默认数据)。
|
||||
* **Install Hooks(安装钩子)** 在安装或升级过程中运行——预安装钩子在元数据迁移之前运行(因此可以拒绝存在风险的升级),后安装钩子在迁移之后运行(因此可以根据新模式写入默认数据)。 卸载钩子会在应用被移除之前立即运行,因此它可以在应用数据仍然可读时清理外部资源。
|
||||
|
||||
<Note>
|
||||
安装钩子与 [logic function](/l/zh/developers/extend/apps/logic/logic-functions) 共用运行时——相同的处理器签名、相同的环境变量、相同的类型化 API 客户端——但它们使用各自的 define 函数声明,并且位于常规触发模型(HTTP、cron、数据库事件)之外。
|
||||
|
||||
@@ -69,7 +69,7 @@ your-app/
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Install flow │
|
||||
│ upload → [pre-install] → metadata migration → │
|
||||
│ generate SDK → [post-install] │
|
||||
│ generate SDK → [post-install] → … → [uninstall] │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ Publish │
|
||||
│ npm publish → appears in Twenty marketplace │
|
||||
@@ -78,13 +78,13 @@ your-app/
|
||||
|
||||
* **`yarn twenty dev`** — 监视你的源文件,并将更改实时同步到已连接的 Twenty 服务器。 当模式发生变化时,会自动重新生成类型化的 API 客户端。
|
||||
* **`yarn twenty dev:build`** — 编译 TypeScript,使用 esbuild 打包逻辑函数和前端组件,并生成清单。
|
||||
* **预/后安装钩子** — 在安装过程中运行的可选函数。 详见 [安装钩子](/l/zh/developers/extend/apps/config/install-hooks)。
|
||||
* **预/后安装和卸载钩子** — 在安装过程中或在卸载前立即运行的可选函数。 详见 [安装钩子](/l/zh/developers/extend/apps/config/install-hooks)。
|
||||
|
||||
## 后续步骤
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="配置" icon="screwdriver-wrench" href="/l/zh/developers/extend/apps/config/overview">
|
||||
应用标识、默认角色和安装钩子。
|
||||
应用标识、默认角色,以及安装和卸载钩子。
|
||||
</Card>
|
||||
<Card title="数据" icon="database" href="/l/zh/developers/extend/apps/data/overview">
|
||||
对象、字段和双向关系。
|
||||
|
||||
@@ -149,7 +149,7 @@ yarn twenty apply # show the plan, then apply it
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="配置" icon="screwdriver-wrench" href="/l/zh/developers/extend/apps/config/overview">
|
||||
应用标识、默认角色、安装钩子、公共资源。
|
||||
应用标识、默认角色、安装和卸载钩子、公共资源。
|
||||
</Card>
|
||||
<Card title="数据" icon="database" href="/l/zh/developers/extend/apps/data/overview">
|
||||
对象、字段和双向关系。
|
||||
|
||||
@@ -613,7 +613,7 @@ const handler = async (params: { parentMessageId?: string }) => {
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
**安装 hooks**——预安装和后安装处理程序——共享此运行时,但使用它们自己的 define 函数进行声明,并且不接受触发器设置。 有关 `definePreInstallLogicFunction` 和 `definePostInstallLogicFunction`,请参阅 [Install Hooks](/l/zh/developers/extend/apps/config/install-hooks)。
|
||||
**安装 hooks**——预安装、后安装和卸载处理程序——共享此运行时,但使用它们自己的 define 函数进行声明,并且不接受触发器设置。 有关 `definePreInstallLogicFunction`、`definePostInstallLogicFunction` 和 `defineUninstallLogicFunction`,请参阅 [Install Hooks](/l/zh/developers/extend/apps/config/install-hooks)。
|
||||
</Note>
|
||||
|
||||
## 类型化 API 客户端(`twenty-client-sdk`)
|
||||
|
||||
@@ -38,9 +38,10 @@ yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
# Pass a JSON payload
|
||||
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
|
||||
# Execute the install hooks
|
||||
# Execute the install and uninstall hooks
|
||||
yarn twenty dev:function:exec --postInstall
|
||||
yarn twenty dev:function:exec --preInstall
|
||||
yarn twenty dev:function:exec --uninstall
|
||||
```
|
||||
|
||||
## 查看函数日志(`yarn twenty dev:function:logs`)
|
||||
|
||||
Reference in New Issue
Block a user