> ## Documentation Index
> Fetch the complete documentation index at: https://twenty-claude-cool-pascal-5ay683.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# App-Konfiguration

> Deklarieren Sie die Identität, die Standardrolle, Variablen und Marktplatz-Metadaten Ihrer App mit `defineApplication`.

Jede App muss genau einen Aufruf von `defineApplication` haben. Dieser deklariert:

* **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-/Uninstall-Hooks** *(optional)* — siehe [Logikfunktionen](/l/de/developers/extend/apps/logic/logic-functions).

```ts src/application-config.ts theme={null}
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,
    },
  },
});
```

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-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.
* Beide Arten von Variablen akzeptieren `isDeprecated: true`. Verwenden Sie dies, um eine Variable außer Betrieb zu nehmen, anstatt sie zu löschen: Wenn der Schlüssel deklariert bleibt, wird der gespeicherte Wert beibehalten (beim Löschen wird der vom Operator eingegebene Wert zerstört), und die Variable wird weiterhin injiziert, sodass Ihr Code darauf zurückfallen kann — `process.env.NEW_API_KEY ?? process.env.API_KEY`. Eine veraltete Variable verschwindet aus den App-Einstellungen, sobald sie keinen Wert mehr hat, und wird niemals bei der Konfigurationsprüfung der App berücksichtigt, sodass `isDeprecated` gegenüber `isRequired` Vorrang hat.
* Um eine benutzerdefinierte Konfigurationsoberfläche im Tab **Settings** der App anzuzeigen (anstelle des standardmäßigen Variablenkonfigurationsbereichs), deklarieren Sie eine Front-Komponente mit [`defineSettingsFrontComponent()`](/l/de/developers/extend/apps/layout/front-components#custom-settings-component) in einer eigenen Datei. Pro App ist nur eine zulässig. Systemverwaltete Bereiche (Auto-Upgrade, App-URL, Verbindungen) bleiben immer sichtbar.

## Variablentypen

Sowohl `applicationVariables` als auch `serverVariables` akzeptieren einen optionalen `type` (und für `SELECT` / `MULTI_SELECT` eine `options`-Liste). Unterstützte Typen: `TEXT` (Standard), `BOOLEAN`, `NUMBER`, `NUMERIC`, `DATE`, `DATE_TIME`, `SELECT`, `MULTI_SELECT`, `ARRAY`, `RAW_JSON`, `RICH_TEXT`.

```ts src/application-config.ts theme={null}
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',
    },
  },
});
```

Der `type` beeinflusst nur die **Darstellung und Validierung** – er wählt das passende Eingabefeld in der UI der Arbeitsbereichseinstellungen aus (Schalter, Zahlenfeld, Dropdown, Datumsauswahl, JSON-Editor, …) und ermöglicht es dem Build, deine Konfiguration zu validieren (zum Beispiel müssen `SELECT` / `MULTI_SELECT` nicht-leere `options` deklarieren). Er ändert **nicht**, wie der Wert deinen Code erreicht.

Werte werden **immer als Strings bereitgestellt** – das ist inhärent bei Umgebungsvariablen (`process.env.*` enthält ausschließlich Strings). Wenn deine Logikfunktion ausgeführt wird, serialisiert der Executor jeden Wert anhand seines deklarierten `type` beim Aufbau von `process.env`, sodass das Stringformat konsistent ist, unabhängig davon, wie der Wert gesetzt wurde (Manifest-Standardwert, Einstellungs-UI oder eine vorherige Version):

| Typ                                   | `process.env`-String                  |
| ------------------------------------- | ------------------------------------- |
| `TEXT`, `SELECT`, `DATE`, `DATE_TIME` | der Rohwert (`"eu"`, `"2026-01-01"`)  |
| `BOOLEAN`                             | `"true"` / `"false"`                  |
| `NUMBER`, `NUMERIC`                   | Dezimal-String (`"10"`, `"2.5"`)      |
| `MULTI_SELECT`, `ARRAY`               | JSON-Array (`'["email","postcard"]'`) |
| `RAW_JSON`, `RICH_TEXT`               | JSON-Objekt (`'{"retries":3}'`)       |

Wandle den String zurück in den erwarteten Typ um:

```ts theme={null}
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 }
```

Das Gleiche gilt für Frontend-Komponenten, die Werte über `getApplicationVariable('VARIABLE_NAME')` lesen – der zurückgegebene Wert ist ein String; wandle ihn bei Bedarf um.

## Standard-Funktionsrolle

Die mit [`defineApplicationRole()`](/l/de/developers/extend/apps/config/roles) deklarierte Rolle steuert, worauf die Logikfunktionen und Frontend-Komponenten der App zugreifen können:

* Die zur Laufzeit in Ihre Logikfunktionen injizierten Token werden aus dieser Rolle abgeleitet. Ein Aufruf, der als Person agiert, wird zusätzlich durch die Möglichkeiten dieser Person eingeschränkt und kann daher niemals eine der beiden Berechtigungen überschreiten. Siehe [Wessen Zugriff ein Aufruf verwendet](/l/de/developers/extend/apps/logic/logic-functions#whose-access-a-call-uses).
* Der typisierte API-Client ist auf die dieser Rolle gewährten Berechtigungen beschränkt.
* Befolgen Sie das Least-Privilege-Prinzip: Deklarieren Sie nur die Berechtigungen, die Ihre Funktionen benötigen.

Wenn Sie eine neue App erzeugen, erstellt die CLI eine Starter-Rolldatei unter `src/roles/default-role.ts`. Die vollständige Referenz finden Sie unter [Rollen & Berechtigungen](/l/de/developers/extend/apps/config/roles).

## Marktplatz-Metadaten

Wenn Sie planen, [Ihre App zu veröffentlichen](/l/de/developers/extend/apps/operations/publishing), steuern diese optionalen Felder, wie Ihre App im Marktplatz erscheint:

| Feld               | Beschreibung                                                                                                                    |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `author`           | Name des Autors oder des Unternehmens                                                                                           |
| `category`         | App-Kategorie für die Filterung im Marktplatz                                                                                   |
| `logo`             | Pfad zu deinem App-Logo in `public/` gebündelt (z.B. `public/logo.png`)                                                         |
| `galleryImages`    | Array der Galerie-Bild-Pfade in `public/` gebündelt (z.B. `public/screenshot-1.png`)                                            |
| `aboutDescription` | Längere Markdown-Beschreibung für den Tab "Info". Wenn weggelassen, verwendet der Marktplatz die `README.md` des Pakets von npm |
| `websiteUrl`       | Link zu Ihrer Website                                                                                                           |
| `termsUrl`         | Link zu den Nutzungsbedingungen                                                                                                 |
| `emailSupport`     | Support-E-Mail-Adresse                                                                                                          |
| `issueReportUrl`   | Link zum Issue-Tracker                                                                                                          |

<Note>
  `logoUrl` und `screenshots` sind veraltete Aliase von `logo` und `galleryImages`. Externe absolute URLs (`http://` oder `https://`) werden für diese Felder nicht unterstützt: Sie werden beim Build mit einer Warnung gelöscht. Bundle stattdessen die Bilder im `public/` Ordner deiner App.
</Note>
