Files
upstream-mirror e7da97194a
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
2026-09-17 23:28:13 +05:00

125 lines
10 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Configurazione dell'applicazione
description: Dichiara l'identità della tua app, il ruolo predefinito, le variabili e i metadati del marketplace con defineApplication.
icon: rocket
---
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 / disinstallazione** *(opzionali)* — vedi [Funzioni logiche](/l/it/developers/extend/apps/logic/logic-functions).
```ts src/application-config.ts
import { defineApplication } from 'twenty-sdk/define';
export default defineApplication({
universalIdentifier: '39783023-bcac-41e3-b0d2-ff1944d8465d',
displayName: 'My Twenty App',
description: 'My first Twenty app',
applicationVariables: {
DEFAULT_RECIPIENT_NAME: {
universalIdentifier: '19e94e59-d4fe-4251-8981-b96d0a9f74de',
description: 'Default recipient name for postcards',
value: 'Jane Doe',
isSecret: false,
},
},
});
```
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, 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.
* Entrambi i tipi di variabile accettano `isDeprecated: true`. Usala per ritirare una variabile invece di eliminarla: mantenere la chiave dichiarata preserva il valore memorizzato (eliminandola si distrugge il valore inserito dall'operatore) e la variabile è ancora iniettata, così il tuo codice può ripiegare su di essa — `process.env.NEW_API_KEY ?? process.env.API_KEY`. Una variabile deprecata scompare dalle impostazioni dell'app non appena non ha più un valore e non viene mai conteggiata nel controllo di configurazione dell'app, quindi `isDeprecated` prevale su `isRequired`.
* Per eseguire il rendering di un'interfaccia di configurazione personalizzata all'interno della scheda **Settings** dell'app (al posto della sezione predefinita di configurazione delle variabili), dichiara un front component con [`defineSettingsFrontComponent()`](/l/it/developers/extend/apps/layout/front-components#custom-settings-component) in un proprio file. Ne è consentito solo uno per app. Le sezioni gestite dal sistema (auto-upgrade, App URL, connessioni) rimangono sempre visibili.
## Tipi di variabili
Sia `applicationVariables` che `serverVariables` accettano un `type` opzionale (e, per `SELECT` / `MULTI_SELECT`, un elenco di `options`). Tipi supportati: `TEXT` (predefinito), `BOOLEAN`, `NUMBER`, `NUMERIC`, `DATE`, `DATE_TIME`, `SELECT`, `MULTI_SELECT`, `ARRAY`, `RAW_JSON`, `RICH_TEXT`.
```ts src/application-config.ts
import { defineApplication, FieldType } from 'twenty-sdk/define';
export default defineApplication({
// ...identity, role...
applicationVariables: {
MAX_POSTCARDS: {
universalIdentifier: '5f4497e4-9030-4085-85eb-2c48b8d53713',
description: 'Maximum postcards per batch',
type: FieldType.NUMBER,
value: 10,
},
DEFAULT_REGION: {
universalIdentifier: '76c5c321-b6b6-46eb-b4fc-f9f04bb04227',
description: 'Default shipping region',
type: FieldType.SELECT,
options: [
{ label: 'Europe', value: 'eu' },
{ label: 'United States', value: 'us' },
],
value: 'eu',
},
},
});
```
Il `type` influisce solo su **presentazione e convalida**: seleziona l’input corrispondente nell’interfaccia delle impostazioni dell’area di lavoro (un interruttore, campo numerico, menu a discesa, selettore di data, editor JSON, …) e consente alla build di convalidare la tua configurazione (ad esempio, `SELECT` / `MULTI_SELECT` devono dichiarare `options` non vuote). **Non** cambia il modo in cui il valore arriva al tuo codice.
I valori sono **sempre inseriti come stringhe**: ciò è intrinseco alle variabili di ambiente (`process.env.*` accetta solo stringhe). Quando la tua funzione di logica viene eseguita, l’executor serializza ogni valore in base al `type` dichiarato mentre costruisce `process.env`, quindi il formato della stringa è coerente indipendentemente da come è stato impostato il valore (valore predefinito del manifest, interfaccia delle impostazioni o una versione precedente):
| Tipo | stringa di `process.env` |
| ------------------------------------- | ----------------------------------------- |
| `TEXT`, `SELECT`, `DATE`, `DATE_TIME` | il valore grezzo (`"eu"`, `"2026-01-01"`) |
| `BOOLEAN` | `"true"` / `"false"` |
| `NUMBER`, `NUMERIC` | stringa decimale (`"10"`, `"2.5"`) |
| `MULTI_SELECT`, `ARRAY` | array JSON (`'["email","postcard"]'`) |
| `RAW_JSON`, `RICH_TEXT` | oggetto JSON (`'{"retries":3}'`) |
Analizza nuovamente la stringa nel tipo che ti aspetti:
```ts
const maxCards = Number(process.env.MAX_POSTCARDS); // "10" -> 10
const enabled = process.env.ENABLE_TRACKING === 'true'; // "true" -> true
const channels = JSON.parse(process.env.ENABLED_CHANNELS ?? '[]'); // '["email"]' -> ["email"]
const config = JSON.parse(process.env.PROVIDER_CONFIG ?? '{}'); // '{"retries":3}' -> { retries: 3 }
```
Lo stesso vale per i componenti front-end che leggono i valori tramite `getApplicationVariable('VARIABLE_NAME')`: il valore restituito è una stringa; analizzalo secondo le necessità.
## Ruolo funzione predefinito
Il ruolo dichiarato con [`defineApplicationRole()`](/l/it/developers/extend/apps/config/roles) controlla a cosa possono accedere le funzioni di logica e i componenti di interfaccia dell'app:
* I token di runtime iniettati nelle funzioni logiche sono derivati da questo ruolo. Una chiamata che agisce come una persona è ulteriormente limitata a ciò che tale persona può fare, quindi non può mai superare nessuno dei due. Vedi [L'accesso utilizzato da una chiamata](/l/it/developers/extend/apps/logic/logic-functions#whose-access-a-call-uses).
* Il client API tipizzato è limitato alle autorizzazioni concesse a quel ruolo.
* Segui il principio del privilegio minimo: dichiara solo le autorizzazioni necessarie alle tue funzioni.
Quando esegui lo scaffolding di una nuova app, la CLI crea un file di ruolo iniziale in `src/roles/default-role.ts`. Per la documentazione completa, vedi [Ruoli e autorizzazioni](/l/it/developers/extend/apps/config/roles).
## Metadati del marketplace
Se prevedi di [pubblicare la tua app](/l/it/developers/extend/apps/operations/publishing), questi campi opzionali controllano come appare nel marketplace:
| Campo | Descrizione |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `author` | Nome dell'autore o dell'azienda |
| `category` | Categoria dell'app per il filtraggio nel marketplace |
| `logo` | Percorso del logo dell'app in bundle in `public/` (ad esempio, `public/logo.png`) |
| `galleryImages` | Array dei percorsi delle immagini della galleria raggruppati in `public/` (ad esempio, `public/screenshot-1.png`) |
| `aboutDescription` | Descrizione markdown più lunga per la scheda "Informazioni". Se omesso, il marketplace utilizza il `README.md` del pacchetto da npm |
| `websiteUrl` | Link al tuo sito web |
| `termsUrl` | Link ai Termini di servizio |
| `emailSupport` | Indirizzo email di supporto |
| `issueReportUrl` | Link al sistema di tracciamento dei problemi |
<Note>
`logoUrl` e `screenshots` sono alias deprecati di `logo` e `galleryImages`. Gli URL assoluti esterni (`http://` o `https://`) non sono supportati per questi campi: vengono eliminati con un avviso al momento della generazione. Raccogli invece le immagini nella cartella `public/` della tua app.
</Note>