Passer au contenu principal
Les applications sont actuellement en phase de test alpha. La fonctionnalité est fonctionnelle mais encore en évolution.

Que sont les applications ?

Les applications vous permettent de créer et de gérer des personnalisations Twenty sous forme de code. Au lieu de tout configurer via l’interface utilisateur, vous définissez votre modèle de données et vos fonctions logiques dans le code — ce qui accélère la création, la maintenance et le déploiement sur plusieurs espaces de travail. Ce que vous pouvez faire aujourd’hui:
  • Définir des objets et des champs personnalisés sous forme de code (modèle de données géré)
  • Créer des fonctions logiques avec des déclencheurs personnalisés
  • Déployer la même application sur plusieurs espaces de travail
Bientôt disponible :
  • Mises en page et composants d’interface utilisateur personnalisés

Prérequis

Prise en main

Créez une nouvelle application avec l’outil d’amorçage officiel, puis authentifiez-vous et commencez à développer :
# Générez une nouvelle application
npx create-twenty-app@latest my-twenty-app
cd my-twenty-app

# Si vous n'utilisez pas yarn@4
corepack enable
yarn install

# Authentifiez-vous avec votre clé API (une invite s'affichera)
yarn auth:login

# Démarrez le mode développement : synchronise automatiquement les modifications locales avec votre espace de travail
yarn app:dev
À partir d’ici, vous pouvez :
# Ajouter une nouvelle entité à votre application (assisté)
yarn entity:add

# Générer un client Twenty typé et les types d'entité de l'espace de travail
yarn app:generate

# Surveiller les journaux des fonctions de votre application
yarn function:logs

# Exécuter une fonction par nom
yarn function:execute -n my-function -p '{"name": "test"}'

# Désinstaller l'application de l'espace de travail actuel
yarn app:uninstall

# Afficher l'aide des commandes
yarn help
Voir aussi : les pages de référence CLI pour create-twenty-app et twenty-sdk CLI.

Structure du projet (générée)

Lorsque vous exécutez npx create-twenty-app@latest my-twenty-app, l’outil de scaffolding :
  • Copie une application de base minimale dans my-twenty-app/
  • Ajoute une dépendance locale à twenty-sdk et la configuration Yarn 4
  • Crée des fichiers de configuration et des scripts reliés à la CLI twenty
  • Génère une configuration d’application par défaut et un rôle de fonction par défaut
Une application nouvellement générée ressemble à ceci :
my-twenty-app/
  package.json
  yarn.lock
  .gitignore
  .nvmrc
  .yarnrc.yml
  .yarn/
    install-state.gz
  eslint.config.mjs
  tsconfig.json
  README.md
  public/                           # Dossier de ressources publiques (images, polices, etc.)
  src/
    application.config.ts          # Obligatoire - configuration principale de l'application
    default-function.role.ts       # Rôle par défaut pour les fonctions serverless
    hello-world.function.ts        # Exemple de fonction serverless
    hello-world.front-component.tsx # Exemple de composant frontal
    // vos entités (*.object.ts, *.function.ts, *.front-component.tsx, *.role.ts)

Convention plutôt que configuration

Les applications adoptent une approche convention plutôt que configuration où les entités sont détectées par leur suffixe de fichier. Cela permet une organisation flexible dans le dossier src/app/ :
Suffixe de fichierType d’entité
*.object.tsDéfinitions d’objets personnalisés
*.function.tsDéfinitions de fonctions sans serveur
*.front-component.tsxDéfinitions des composants frontaux
*.role.tsDéfinitions de rôles

Structures de dossiers prises en charge

Vous pouvez organiser vos entités selon l’un des schémas suivants : Traditionnelle (par type) :
src/
├── application.config.ts
├── objects/
│   └── postCard.object.ts
├── functions/
│   └── createPostCard.function.ts
├── components/
│   └── card.front-component.tsx
└── roles/
    └── admin.role.ts
Par fonctionnalité :
src/
├── application.config.ts
└── post-card/
    ├── postCard.object.ts
    ├── createPostCard.function.ts
    ├── card.front-component.tsx
    └── postCardAdmin.role.ts
À plat :
src/
├── application.config.ts
├── postCard.object.ts
├── createPostCard.function.ts
├── card.front-component.tsx
└── admin.role.ts
Dans les grandes lignes :
  • package.json : Déclare le nom de l’application, la version, les moteurs (Node 24+, Yarn 4), et ajoute twenty-sdk ainsi que des scripts comme app:dev, app:generate, entity:add, function:logs, function:execute, app:uninstall et auth:login qui délèguent à la CLI locale twenty.
  • .gitignore : Ignore les artefacts courants tels que node_modules, .yarn, generated/ (client typé), dist/, build/, les dossiers de couverture, les fichiers journaux et les fichiers .env*.
  • yarn.lock, .yarnrc.yml, .yarn/ : Verrouillent et configurent la chaîne d’outils Yarn 4 utilisée par le projet.
  • .nvmrc : Fige la version de Node.js attendue par le projet.
  • eslint.config.mjs et tsconfig.json : Fournissent la configuration de linting et TypeScript pour les sources TypeScript de votre application.
  • README.md : Un bref README à la racine de l’application avec des instructions de base.
  • public/: Un dossier pour stocker des ressources publiques (images, polices, fichiers statiques) qui seront servies avec votre application. Les fichiers placés ici sont téléversés lors de la synchronisation et accessibles à l’exécution.
  • src/ : L’endroit principal où vous définissez votre application sous forme de code :
    • application.config.ts : Configuration globale de votre application (métadonnées et liaisons d’exécution). Voir « Configuration de l’application » ci-dessous.
    • *.role.ts : Définitions de rôles utilisées par vos fonctions logiques. Voir « Rôle de fonction par défaut » ci-dessous.
    • *.object.ts : Définitions d’objets personnalisés.
    • *.function.ts : Définitions de fonctions logiques.
    • *.front-component.tsx : Définitions des composants front-end.
Des commandes ultérieures ajouteront d’autres fichiers et dossiers :
  • yarn app:generate créera un dossier generated/ (client Twenty typé + types de l’espace de travail).
  • yarn entity:add ajoutera des fichiers de définition d’entité sous src/ pour vos objets, fonctions, composants front-end ou rôles personnalisés.

Authentification

La première fois que vous exécutez yarn auth:login, il vous sera demandé :
  • URL de l’API (par défaut http://localhost:3000 ou votre profil d’espace de travail actuel)
  • Clé API
Vos identifiants sont stockés par utilisateur dans ~/.twenty/config.json. Vous pouvez gérer plusieurs profils et basculer entre eux.

Gestion des espaces de travail

# Login interactively (recommended)
yarn auth:login

# Login to a specific workspace profile
yarn auth:login --workspace my-custom-workspace

# List all configured workspaces
yarn auth:list

# Switch the default workspace (interactive)
yarn auth:switch

# Switch to a specific workspace
yarn auth:switch production

# Check current authentication status
yarn auth:status
Une fois que vous avez changé d’espace de travail avec auth:switch, toutes les commandes suivantes utiliseront cet espace de travail par défaut. Vous pouvez toujours le surcharger temporairement avec --workspace <name>.

Utiliser les ressources du SDK (types et configuration)

Le paquet twenty-sdk fournit des blocs de construction typés et des fonctions utilitaires que vous utilisez dans votre application. Voici les éléments clés que vous manipulerez le plus souvent.

Fonctions utilitaires

Le SDK fournit quatre fonctions utilitaires avec validation intégrée pour définir les entités de votre application :
FonctionObjectif
defineApplication()Configurer les métadonnées de l’application
defineObject()Définir des objets personnalisés avec des champs
defineFunction()Définir des fonctions logiques avec des gestionnaires
defineRole()Configurer les autorisations de rôle et l’accès aux objets
Ces fonctions valident votre configuration à l’exécution et offrent une meilleure autocomplétion IDE et une sécurité de typage accrue.

Définir des objets

Les objets personnalisés décrivent à la fois le schéma et le comportement des enregistrements dans votre espace de travail. Utilisez defineObject() pour définir des objets avec validation intégrée :
// src/app/postCard.object.ts
import { defineObject, FieldType } from 'twenty-sdk';

enum PostCardStatus {
  DRAFT = 'DRAFT',
  SENT = 'SENT',
  DELIVERED = 'DELIVERED',
  RETURNED = 'RETURNED',
}

export default defineObject({
  universalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05',
  nameSingular: 'postCard',
  namePlural: 'postCards',
  labelSingular: 'Post Card',
  labelPlural: 'Post Cards',
  description: 'A post card object',
  icon: 'IconMail',
  fields: [
    {
      universalIdentifier: '58a0a314-d7ea-4865-9850-7fb84e72f30b',
      name: 'content',
      type: FieldType.TEXT,
      label: 'Content',
      description: "Postcard's content",
      icon: 'IconAbc',
    },
    {
      universalIdentifier: 'c6aa31f3-da76-4ac6-889f-475e226009ac',
      name: 'recipientName',
      type: FieldType.FULL_NAME,
      label: 'Recipient name',
      icon: 'IconUser',
    },
    {
      universalIdentifier: '95045777-a0ad-49ec-98f9-22f9fc0c8266',
      name: 'recipientAddress',
      type: FieldType.ADDRESS,
      label: 'Recipient address',
      icon: 'IconHome',
    },
    {
      universalIdentifier: '87b675b8-dd8c-4448-b4ca-20e5a2234a1e',
      name: 'status',
      type: FieldType.SELECT,
      label: 'Status',
      icon: 'IconSend',
      defaultValue: `'${PostCardStatus.DRAFT}'`,
      options: [
        { value: PostCardStatus.DRAFT, label: 'Draft', position: 0, color: 'gray' },
        { value: PostCardStatus.SENT, label: 'Sent', position: 1, color: 'orange' },
        { value: PostCardStatus.DELIVERED, label: 'Delivered', position: 2, color: 'green' },
        { value: PostCardStatus.RETURNED, label: 'Returned', position: 3, color: 'orange' },
      ],
    },
    {
      universalIdentifier: 'e06abe72-5b44-4e7f-93be-afc185a3c433',
      name: 'deliveredAt',
      type: FieldType.DATE_TIME,
      label: 'Delivered at',
      icon: 'IconCheck',
      isNullable: true,
      defaultValue: null,
    },
  ],
});
Points clés :
  • Utilisez defineObject() pour une validation intégrée et une meilleure prise en charge par l’IDE.
  • Le universalIdentifier doit être unique et stable entre les déploiements.
  • Chaque champ nécessite un name, un type, un label et son propre universalIdentifier stable.
  • Le tableau fields est facultatif — vous pouvez définir des objets sans champs personnalisés.
  • Vous pouvez générer de nouveaux objets avec yarn entity:add, qui vous guide à travers le nommage, les champs et les relations.
Les champs de base sont créés automatiquement. Lorsque vous définissez un objet personnalisé, Twenty ajoute automatiquement des champs standard tels que name, createdAt, updatedAt, createdBy, position et deletedAt. Vous n’avez pas besoin de les définir dans votre tableau fields — ajoutez uniquement vos champs personnalisés.

Configuration de l’application (application.config.ts)

Chaque application dispose d’un seul fichier application.config.ts qui décrit :
  • Identité de l’application : identifiants, nom d’affichage et description.
  • Exécution des fonctions : le rôle utilisé pour les autorisations.
  • Variables (facultatif) : paires clé–valeur exposées à vos fonctions en tant que variables d’environnement.
Utilisez defineApplication() pour définir la configuration de votre application :
// src/app/application.config.ts
import { defineApplication } from 'twenty-sdk';
import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from './default-function.role';

export default defineApplication({
  universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
  displayName: 'My Twenty App',
  description: 'My first Twenty app',
  icon: 'IconWorld',
  applicationVariables: {
    DEFAULT_RECIPIENT_NAME: {
      universalIdentifier: '19e94e59-d4fe-4251-8981-b96d0a9f74de',
      description: 'Default recipient name for postcards',
      value: 'Jane Doe',
      isSecret: false,
    },
  },
  defaultRoleUniversalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
});
Notes :
  • Les champs universalIdentifier sont des identifiants déterministes que vous possédez ; générez-les une fois et conservez-les stables entre les synchronisations.
  • applicationVariables deviennent des variables d’environnement pour vos fonctions (par exemple, DEFAULT_RECIPIENT_NAME est disponible sous process.env.DEFAULT_RECIPIENT_NAME).
  • defaultRoleUniversalIdentifier doit correspondre au rôle que vous définissez dans votre fichier *.role.ts (voir ci-dessous).

Rôles et autorisations

Les applications peuvent définir des rôles qui encapsulent des autorisations sur les objets et actions de votre espace de travail. Le champ defaultRoleUniversalIdentifier dans application.config.ts désigne le rôle par défaut utilisé par les fonctions logiques de votre application.
  • La clé API d’exécution injectée sous TWENTY_API_KEY est dérivée de ce rôle de fonction par défaut.
  • Le client typé sera limité aux autorisations accordées à ce rôle.
  • Appliquez le principe du moindre privilège : créez un rôle dédié avec uniquement les autorisations nécessaires à vos fonctions, puis référencez son identifiant universel.
Rôle de fonction par défaut (*.role.ts)
Lorsque vous générez une nouvelle application, la CLI crée également un fichier de rôle par défaut. Utilisez defineRole() pour définir des rôles avec validation intégrée :
// src/app/default-function.role.ts
import { defineRole, PermissionFlag } from 'twenty-sdk';

export const DEFAULT_ROLE_UNIVERSAL_IDENTIFIER =
  'b648f87b-1d26-4961-b974-0908fd991061';

export default defineRole({
  universalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
  label: 'Default function role',
  description: 'Default role for function Twenty client',
  canReadAllObjectRecords: false,
  canUpdateAllObjectRecords: false,
  canSoftDeleteAllObjectRecords: false,
  canDestroyAllObjectRecords: false,
  canUpdateAllSettings: false,
  canBeAssignedToAgents: false,
  canBeAssignedToUsers: false,
  canBeAssignedToApiKeys: false,
  objectPermissions: [
    {
      objectUniversalIdentifier: '9f9882af-170c-4879-b013-f9628b77c050',
      canReadObjectRecords: true,
      canUpdateObjectRecords: true,
      canSoftDeleteObjectRecords: false,
      canDestroyObjectRecords: false,
    },
  ],
  fieldPermissions: [
    {
      objectUniversalIdentifier: '9f9882af-170c-4879-b013-f9628b77c050',
      fieldUniversalIdentifier: 'b2c37dc0-8ae7-470e-96cd-1476b47dfaff',
      canReadFieldValue: false,
      canUpdateFieldValue: false,
    },
  ],
  permissionFlags: [PermissionFlag.APPLICATIONS],
});
Le universalIdentifier de ce rôle est ensuite référencé dans application.config.ts en tant que defaultRoleUniversalIdentifier. En d’autres termes :
  • *.role.ts définit ce que le rôle de fonction par défaut peut faire.
  • application.config.ts pointe vers ce rôle afin que vos fonctions héritent de ses autorisations.
Notes :
  • Partez du rôle généré, puis restreignez-le progressivement en suivant le principe du moindre privilège.
  • Remplacez objectPermissions et fieldPermissions par les objets/champs dont vos fonctions ont besoin.
  • permissionFlags contrôlent l’accès aux capacités au niveau de la plateforme. Gardez-les au minimum ; n’ajoutez que ce dont vous avez besoin.
  • Voir un exemple fonctionnel dans l’application Hello World : packages/twenty-apps/hello-world/src/roles/function-role.ts.

Configuration et point d’entrée des fonctions logiques

Chaque fichier de fonction utilise defineFunction() pour exporter une configuration avec un gestionnaire et des déclencheurs facultatifs. Utilisez le suffixe de fichier *.function.ts pour la détection automatique.
// src/app/createPostCard.function.ts
import { defineFunction } from 'twenty-sdk';
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk';
import Twenty, { type Person } from '~/generated';

const handler = async (params: RoutePayload) => {
  const client = new Twenty(); // generated typed client
  const name = 'name' in params.queryStringParameters
    ? params.queryStringParameters.name ?? process.env.DEFAULT_RECIPIENT_NAME ?? 'Hello world'
    : 'Hello world';

  const result = await client.mutation({
    createPostCard: {
      __args: { data: { name } },
      id: true,
      name: true,
    },
  });
  return result;
};

export default defineFunction({
  universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
  name: 'create-new-post-card',
  timeoutSeconds: 2,
  handler,
  triggers: [
    // Public HTTP route trigger '/s/post-card/create'
    {
      universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
      type: 'route',
      path: '/post-card/create',
      httpMethod: 'GET',
      isAuthRequired: false,
    },
    // Cron trigger (CRON pattern)
    // {
    //   universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
    //   type: 'cron',
    //   pattern: '0 0 1 1 *',
    // },
    // Database event trigger
    // {
    //   universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
    //   type: 'databaseEvent',
    //   eventName: 'person.updated',
    //   updatedFields: ['name'],
    // },
  ],
});
Types de déclencheurs courants :
  • route : Expose votre fonction sur un chemin et une méthode HTTP sous l’endpoint /s/ :
p. ex. path: '/post-card/create', -> appel sur <APP_URL>/s/post-card/create
  • cron : Exécute votre fonction selon une planification à l’aide d’une expression CRON.
  • databaseEvent: S’exécute lors des événements du cycle de vie des objets de l’espace de travail. Lorsque l’opération de l’événement est updated, des champs spécifiques à surveiller peuvent être spécifiés dans le tableau updatedFields. S’il est laissé indéfini ou vide, toute mise à jour déclenchera la fonction.
p. ex. person.updated
Notes :
  • Le tableau triggers est facultatif. Les fonctions sans déclencheurs peuvent servir de fonctions utilitaires appelées par d’autres fonctions.
  • Vous pouvez combiner plusieurs types de déclencheurs dans une seule fonction.

Charge utile du déclencheur de route

Changement incompatible (v1.16, janvier 2026): Le format de la charge utile du déclencheur de route a changé. Avant la v1.16, les paramètres de requête, les paramètres de chemin et le corps de la requête étaient envoyés directement en tant que charge utile. À partir de la v1.16, ils sont imbriqués dans un objet RoutePayload structuré.Avant la v1.16 :
const handler = async (params) => {
  const { param1, param2 } = params; // Direct access
};
Après la v1.16 :
const handler = async (event: RoutePayload) => {
  const { param1, param2 } = event.body; // Access via .body
  const { queryParam } = event.queryStringParameters;
  const { id } = event.pathParameters;
};
Pour migrer les fonctions existantes : Mettez à jour votre gestionnaire pour déstructurer à partir de event.body, event.queryStringParameters ou event.pathParameters plutôt que directement à partir de l’objet params.
Lorsqu’un déclencheur de route appelle votre fonction logique, elle reçoit un objet RoutePayload qui suit le format AWS HTTP API v2. Importez le type depuis twenty-sdk :
import { defineFunction, type RoutePayload } from 'twenty-sdk';

const handler = async (event: RoutePayload) => {
  // Access request data
  const { headers, queryStringParameters, pathParameters, body } = event;

  // HTTP method and path are available in requestContext
  const { method, path } = event.requestContext.http;

  return { message: 'Success' };
};
Le type RoutePayload a la structure suivante :
Nom de la propriétéTypeDescription
headersRecord<string, string | undefined>En-têtes HTTP (uniquement ceux répertoriés dans forwardedRequestHeaders)
queryStringParametersRecord<string, string | undefined>Paramètres de la chaîne de requête (plusieurs valeurs séparées par des virgules)
pathParametersRecord<string, string | undefined>Paramètres de chemin extraits du modèle de route (p. ex., /users/:id{ id: '123' })
corps du messageobject | nullCorps de la requête analysé (JSON)
isBase64EncodedbooléenIndique si le corps est encodé en base64
requestContext.http.methodstringMéthode HTTP (GET, POST, PUT, PATCH, DELETE)
requestContext.http.pathstringChemin de la requête brut

Transfert des en-têtes HTTP

Par défaut, les en-têtes HTTP des requêtes entrantes ne sont pas transmis à votre fonction logique pour des raisons de sécurité. Pour accéder à des en-têtes spécifiques, listez-les explicitement dans le tableau forwardedRequestHeaders :
export default defineFunction({
  universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
  name: 'webhook-handler',
  handler,
  triggers: [
    {
      universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
      type: 'route',
      path: '/webhook',
      httpMethod: 'POST',
      isAuthRequired: false,
      forwardedRequestHeaders: ['x-webhook-signature', 'content-type'],
    },
  ],
});
Dans votre gestionnaire, vous pouvez ensuite accéder à ces en-têtes :
const handler = async (event: RoutePayload) => {
  const signature = event.headers['x-webhook-signature'];
  const contentType = event.headers['content-type'];

  // Validate webhook signature...
  return { received: true };
};
Les noms d’en-têtes sont normalisés en minuscules. Accédez-y en utilisant des clés en minuscules (par exemple, event.headers['content-type']).
Vous pouvez créer de nouvelles fonctions de deux façons :
  • Générée : Exécutez yarn entity:add et choisissez l’option pour ajouter une nouvelle fonction. Cela génère un fichier de démarrage avec un gestionnaire et une configuration.
  • Manuelle : Créez un nouveau fichier *.function.ts et utilisez defineFunction(), en suivant le même modèle.

Client typé généré

Exécutez yarn app:generate pour créer un client typé local dans generated/ basé sur le schéma de votre espace de travail. Utilisez-le dans vos fonctions :
import Twenty from '~/generated';

const client = new Twenty();
const { me } = await client.query({ me: { id: true, displayName: true } });
Le client est régénéré par yarn app:generate. Relancez après avoir modifié vos objets ou lors de l’intégration à un nouvel espace de travail.

Identifiants d’exécution dans les fonctions logiques

Lorsque votre fonction s’exécute sur Twenty, la plateforme injecte des identifiants sous forme de variables d’environnement avant l’exécution de votre code :
  • TWENTY_API_URL : URL de base de l’API Twenty ciblée par votre application.
  • TWENTY_API_KEY : Clé de courte durée limitée au rôle de fonction par défaut de votre application.
Notes:
  • Vous n’avez pas besoin de passer l’URL ou la clé API au client généré. Il lit TWENTY_API_URL et TWENTY_API_KEY depuis process.env à l’exécution.
  • Les autorisations de la clé API sont déterminées par le rôle référencé dans votre application.config.ts via defaultRoleUniversalIdentifier. Il s’agit du rôle par défaut utilisé par les fonctions logiques de votre application.
  • Les applications peuvent définir des rôles pour appliquer le principe du moindre privilège. N’accordez que les autorisations dont vos fonctions ont besoin, puis faites pointer defaultRoleUniversalIdentifier vers l’identifiant universel de ce rôle.

Exemple Hello World

Découvrez un exemple minimal de bout en bout qui démontre des objets, des fonctions et plusieurs déclencheurs ici :

Configuration manuelle (sans l’outil de scaffolding)

Même si nous recommandons d’utiliser create-twenty-app pour une expérience de démarrage optimale, vous pouvez également configurer un projet manuellement. N’installez pas la CLI globalement. Ajoutez plutôt twenty-sdk comme dépendance locale et reliez des scripts dans votre package.json :
yarn add -D twenty-sdk
Ajoutez ensuite des scripts comme ceux-ci :
{
  "scripts": {
    "auth:login": "twenty auth:login",
    "auth:logout": "twenty auth:logout",
    "auth:status": "twenty auth:status",
    "auth:switch": "twenty auth:switch",
    "auth:list": "twenty auth:list",
    "app:dev": "twenty app:dev",
    "app:generate": "twenty app:generate",
    "app:uninstall": "twenty app:uninstall",
    "entity:add": "twenty entity:add",
    "function:logs": "twenty function:logs",
    "function:execute": "twenty function:execute",
    "help": "twenty help"
  }
}
Vous pouvez désormais exécuter les mêmes commandes via Yarn, par exemple yarn app:dev, yarn app:generate, etc.

Résolution des problèmes

  • Erreurs d’authentification : exécutez yarn auth:login et assurez-vous que votre clé API dispose des autorisations requises.
  • Impossible de se connecter au serveur : vérifiez l’URL de l’API et que le serveur Twenty est accessible.
  • Types ou client manquants/obsolètes : exécutez yarn app:generate.
  • Le mode dev ne se synchronise pas : assurez-vous que yarn app:dev est en cours d’exécution et que les modifications ne sont pas ignorées par votre environnement.
Canal d’aide Discord : https://discord.com/channels/1130383047699738754/1130386664812982322