Compare commits

..
2804 Commits
Author SHA1 Message Date
Paul Rastoinandprastoin ad75662919 Non composite and non morph or relation field update fix (#16091) 2025-11-26 12:57:44 +01:00
Paul Rastoinandprastoin aa7c5a778b Refactor upgrade devx to allow configuring workspaces status to pass over (#16066)
We need to be able to create custom workspace application on all
workspaces, even pending and ongoing etc
Right now the upgrade devx only allows and expect active or suspended
workspace to be passed to runOnWorkspace.

Created an intermediate class `WorkspacesMigrationRunner` that expect an
array `WorkspaceStatus` to be fetched for the current command to be run
on
The `ActiveOrSuspendedCommandRunner` statically passes both `SUSPENDED`
and `ACTIVE`, whereas the create workspace custom application passed all
the enum values

Workspace that are not fully init don't have a `workspace_schema` so
they don't have `dataSource`
Made a not very elegant check to see if current workspace we're about to
create dataSource on has one historically
Which means that dataSource is now optional, it had only one impact on
an existing command and the desired devx will become consuming existing
services that do not expect dataSource ( or at least yet )
2025-11-26 12:57:33 +01:00
Charles Bochet 8d43ed4515 Fix message import scheduled 2025-11-25 19:24:00 +01:00
Baptiste DevessierandCharles Bochet 3d1d3d9f04 [Side Panel V2] Bring back old container (#16065)
## Before

<img width="1446" height="780" alt="image"
src="https://github.com/user-attachments/assets/fa25f22d-b979-4a8f-9989-004d07f862d7"
/>

## After

<img width="3456" height="2160" alt="CleanShot 2025-11-25 at 17 35
59@2x"
src="https://github.com/user-attachments/assets/a87880c4-3faa-47c3-9215-34afc36270a3"
/>
2025-11-25 18:16:32 +01:00
EtienneandCharles Bochet b19dc703cc Security - disable gql introspection for non-auth user (#16047)
closes https://github.com/twentyhq/private-issues/issues/351
closes https://github.com/twentyhq/private-issues/issues/350

Before, introspection query works without token. After, fails.

```

query IntrospectionQuery {
  __schema {
    queryType {
      name
    }
    mutationType {
      name
    }
    subscriptionType {
      name
    }
    types {
      ...FullType
    }
    directives {
      name
      description
      locations
      args {
        ...InputValue
      }
    }
  }
}

fragment FullType on __Type {
  kind
  name
  description
  fields(includeDeprecated: true) {
    name
    description
    args {
      ...InputValue
    }
    type {
      ...TypeRef
    }
    isDeprecated
    deprecationReason
  }
  inputFields {
    ...InputValue
  }
  interfaces {
    ...TypeRef
  }
  enumValues(includeDeprecated: true) {
    name
    description
    isDeprecated
    deprecationReason
  }
  possibleTypes {
    ...TypeRef
  }
}

fragment InputValue on __InputValue {
  name
  description
  type {
    ...TypeRef
  }
  defaultValue
}

fragment TypeRef on __Type {
  kind
  name
  ofType {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
              }
            }
          }
        }
      }
    }
  }
}
```
2025-11-25 18:16:07 +01:00
neo773andCharles Bochet 9b668619c5 Update channel sync service to immediately enqueue jobs (#16064) 2025-11-25 18:15:57 +01:00
neo773andCharles Bochet e7c83dc04f move folder cron to message-list-fetch (#16062) 2025-11-25 18:15:49 +01:00
Charles BochetandCharles Bochet 693fe01fa4 Fix upgrade command messaging (#16067) 2025-11-25 18:15:42 +01:00
Charles BochetandCharles Bochet c616713435 Add import scheduled status to messaging sync (#16058)
We have introduced to new syncStage statuses:
`messageChannel.MESSAGES_IMPORT_SCHEDULED` and
`calendarChannel.CALENDAR_EVENTS_IMPORT_SCHEDULED`

We need to make sure all existing workspaces have it
2025-11-25 15:28:48 +01:00
Raphaël Bosiandprastoin 859c948d01 Fix page layout widget deletion (#16035)
With the new side panel, we are able to delete a widget with the side
panel still open. This caused the app to crash because we threw when the
widget id wasn't defined.

This PR fixes this by closing the side panel in the delete action and by
returning null instead of throwing.

## Before



https://github.com/user-attachments/assets/092bfe62-82dc-4d83-9967-1cc753ecf55e



## After


https://github.com/user-attachments/assets/8bed6cc5-961b-4112-8cf5-e587865d14da
2025-11-25 14:08:39 +01:00
3ed6d2a16b i18n - translations (#16034)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-24 18:20:39 +01:00
Paul RastoinandGitHub 439adc6ac0 Restore transaction on WorkspaceCustomApplicationIdNonNullable1763977334519 failure (#16032)
# Introduction
When a transaction query fails it gets aborted, even if we catch the js
exception typeorm ack it and fails
By adding a save point we isolate the issue and restore the transaction
🥷

## Through database:migrate:prod
Tested but lost logs

## Upgrade
```ts

➜  twenty-server git:(fix-migration-runner) ✗ npx nx command twenty-server upgrade

   ✔  3/3 dependent project tasks succeeded [3 read from cache]

   Hint: you can run the command with --verbose to see the full dependent project outputs

———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————


> nx run twenty-server:build  [existing outputs match the cache, left as is]

> rimraf dist

> nest build --path ./tsconfig.build.json

>  SWC  Running...
Successfully compiled: 3747 files with swc (65.82ms)

> nx run twenty-server:command upgrade

query: SELECT * FROM current_schema()
query: SELECT version();
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [NestFactory] Starting Nest application...
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [InstanceLoader] CommandRootModule dependencies initialized
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [InstanceLoader] CommandModule dependencies initialized
// ...
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [InstanceLoader] WorkflowApiModule dependencies initialized
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [InstanceLoader] AuthModule dependencies initialized
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [PgPoolSharedService] Pool sharing will use max 10 connections per pool with 600000ms idle timeout and allowExitOnIdle=true
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [PgPoolSharedService] pg.Pool patched successfully by this service instance.
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [PgPoolSharedService] Pg pool sharing initialized - pools will be shared across tenants
[Nest] 82844  - 11/24/2025, 6:05:11 PM   DEBUG [PgPoolSharedService] No active pg pools to log stats for
[Nest] 82844  - 11/24/2025, 6:05:11 PM   DEBUG [PgPoolSharedService] Pool statistics logging enabled (30s interval)
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [PgPoolSharedService] Created new shared pg Pool for key "localhost|5432|postgres||no-ssl" with 10 max connections and 600000 ms idle timeout. Total pools: 1
[Nest] 82844  - 11/24/2025, 6:05:11 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: New connection established
[Nest] 82844  - 11/24/2025, 6:05:11 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: Client acquired from pool
[Nest] 82844  - 11/24/2025, 6:05:11 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: Client acquired from pool
[Nest] 82844  - 11/24/2025, 6:05:11 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: Client acquired from pool
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [DatabaseConfigDriver] [INIT] Loading initial config variables from database
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [DatabaseConfigDriver] [INIT] Config variables loaded: 0 values found in DB, 59 falling to env vars/defaults
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [UpgradeCommand] Initialized upgrade context with:
   - currentVersion (migrating to): 1.12.0
   - fromWorkspaceVersion: 1.11.0
   - 3 commands
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [UpgradeCommand] Running global database migrations
[Nest] 82844  - 11/24/2025, 6:05:11 PM     LOG [UpgradeCommand] Running core datasource migrations...
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [UpgradeCommand] query: SELECT * FROM current_schema()
query: CREATE EXTENSION IF NOT EXISTS "uuid-ossp"
query: SELECT version();
query: SELECT * FROM "information_schema"."tables" WHERE "table_schema" = 'core' AND "table_name" = '_typeorm_migrations'
query: SELECT * FROM "core"."_typeorm_migrations" "_typeorm_migrations" ORDER BY "id" DESC
46 migrations are already loaded in the database.
47 migrations were found in the source code.
AddCanBeUninstalledColumnToApplication1763731277403 is the last executed migration. It was executed on Fri Nov 21 2025 14:21:17 GMT+0100 (Central European Standard Time).
1 migrations are new migrations must be executed.
query: START TRANSACTION
query: SAVEPOINT sp_workspace_custom_application_id_non_nullable
query: ALTER TABLE "core"."workspace" DROP CONSTRAINT "FK_3b1acb13a5dac9956d1a4b32755"
query: ALTER TABLE "core"."workspace" ALTER COLUMN "workspaceCustomApplicationId" SET NOT NULL
query failed: ALTER TABLE "core"."workspace" ALTER COLUMN "workspaceCustomApplicationId" SET NOT NULL
error: error: column "workspaceCustomApplicationId" of relation "workspace" contains null values
query: ROLLBACK TO SAVEPOINT sp_workspace_custom_application_id_non_nullable
query: RELEASE SAVEPOINT sp_workspace_custom_application_id_non_nullable
query: INSERT INTO "core"."_typeorm_migrations"("timestamp", "name") VALUES ($1, $2) -- PARAMETERS: [1763977334519,"WorkspaceCustomApplicationIdNonNullable1763977334519"]
Migration WorkspaceCustomApplicationIdNonNullable1763977334519 has been  executed successfully.
query: COMMIT

[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [UpgradeCommand] Database migrations completed successfully
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [UpgradeCommand] Running command on workspace 20202020-1c25-4d02-bf25-6aeccf7ea419 1/2
Computing new Datasource for cacheKey: 20202020-1c25-4d02-bf25-6aeccf7ea419-10 out of 0
[Nest] 82844  - 11/24/2025, 6:05:12 PM   DEBUG [PgPoolSharedService] Reusing existing pg Pool for key "localhost|5432|postgres||no-ssl"
[Nest] 82844  - 11/24/2025, 6:05:12 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: Client acquired from pool
[Nest] 82844  - 11/24/2025, 6:05:12 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: Client acquired from pool
query: SELECT * FROM current_schema()
[Nest] 82844  - 11/24/2025, 6:05:12 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: Client acquired from pool
query: SELECT version();
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [UpgradeCommand] Upgrading workspace 20202020-1c25-4d02-bf25-6aeccf7ea419 from=1.11.0 to=1.12.0 1/2
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [CreateWorkspaceCustomApplicationCommand] Checking standard applications for workspace 20202020-1c25-4d02-bf25-6aeccf7ea419
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [CreateWorkspaceCustomApplicationCommand] 20202020-1c25-4d02-bf25-6aeccf7ea419 skipping custom workspace application creation as already exists
query failed: ALTER TABLE "core"."workspace" ALTER COLUMN "workspaceCustomApplicationId" SET NOT NULL
error: error: column "workspaceCustomApplicationId" of relation "workspace" contains null values
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceCustomApplicationIdNonNullableCommand] Rollbacking WorkspaceCustomApplicationIdNonNullableCommand: column "workspaceCustomApplicationId" of relation "workspace" contains null values
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [SyncWorkspaceMetadataCommand] Running workspace sync for workspace: 20202020-1c25-4d02-bf25-6aeccf7ea419 (0 out of 2)
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncMetadataService] Syncing standard objects and fields metadata
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncMetadataService] Syncing standard objects and fields metadata
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncObjectMetadataService] Comparing standard objects and fields metadata
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncObjectMetadataService] Updating workspace metadata
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncObjectMetadataService] Generating migrations
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncObjectMetadataService] Saving migrations
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncMetadataService] Workspace object migrations took 50.206083000000035ms
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncFieldMetadataService] Updating workspace metadata
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncFieldMetadataService] Generating migrations
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncFieldMetadataService] Saving migrations
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncMetadataService] Workspace field migrations took 79.43987500000003ms
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncFieldMetadataRelationService] Updating workspace metadata
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncFieldMetadataRelationService] Generating migrations
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncFieldMetadataRelationService] Saving migrations
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncMetadataService] Workspace relation migrations took 91.85295899999983ms
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncIndexMetadataService] Syncing index metadata
[Nest] 82844  - 11/24/2025, 6:05:12 PM     LOG [WorkspaceSyncMetadataService] Workspace index migrations took 153.78104199999962ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace object metadata identifiers took 130.9623330000004ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncRoleService] Syncing standard role metadata
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace role migrations took 2.154790999999932ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncAgentService] Syncing standard agent.
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace agent migrations took 2.3623329999991256ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace migrations save took 5.95837500000016ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Executing pending migrations
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Execute migrations took 66.94295799999963ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [SyncWorkspaceMetadataCommand] Finished synchronizing workspace.
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [SetStandardApplicationNotUninstallableCommand] Checking workspace applications for workspace 20202020-1c25-4d02-bf25-6aeccf7ea419
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [SetStandardApplicationNotUninstallableCommand] Successfully updated workspace application
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [UpgradeCommand] Upgrade for workspace 20202020-1c25-4d02-bf25-6aeccf7ea419 completed.
PromiseMemoizer Event: A WorkspaceDataSource for workspace 20202020-1c25-4d02-bf25-6aeccf7ea419 is being cleared. Actual pool closure managed by PgPoolSharedService. Not calling dataSource.destroy().
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [UpgradeCommand] Running command on workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db 2/2
Computing new Datasource for cacheKey: 3b8e6458-5fc1-4e63-8563-008ccddaa6db-6 out of 0
[Nest] 82844  - 11/24/2025, 6:05:13 PM   DEBUG [PgPoolSharedService] Reusing existing pg Pool for key "localhost|5432|postgres||no-ssl"
[Nest] 82844  - 11/24/2025, 6:05:13 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: Client acquired from pool
[Nest] 82844  - 11/24/2025, 6:05:13 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: Client acquired from pool
query: SELECT * FROM current_schema()
[Nest] 82844  - 11/24/2025, 6:05:13 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: Client acquired from pool
query: SELECT version();
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [UpgradeCommand] Upgrading workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db from=1.11.0 to=1.12.0 2/2
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [CreateWorkspaceCustomApplicationCommand] Checking standard applications for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [CreateWorkspaceCustomApplicationCommand] Successfully create workspace custom application
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceCustomApplicationIdNonNullableCommand] Successfully run WorkspaceCustomApplicationIdNonNullableCommand
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [SyncWorkspaceMetadataCommand] Running workspace sync for workspace: 3b8e6458-5fc1-4e63-8563-008ccddaa6db (1 out of 2)
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Syncing standard objects and fields metadata
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Syncing standard objects and fields metadata
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncObjectMetadataService] Comparing standard objects and fields metadata
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncObjectMetadataService] Updating workspace metadata
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncObjectMetadataService] Generating migrations
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncObjectMetadataService] Saving migrations
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace object migrations took 19.26008400000046ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncFieldMetadataService] Updating workspace metadata
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncFieldMetadataService] Generating migrations
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncFieldMetadataService] Saving migrations
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace field migrations took 31.371917000000394ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncFieldMetadataRelationService] Updating workspace metadata
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncFieldMetadataRelationService] Generating migrations
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncFieldMetadataRelationService] Saving migrations
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace relation migrations took 36.84983300000022ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncIndexMetadataService] Syncing index metadata
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace index migrations took 43.85666599999968ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace object metadata identifiers took 74.27345799999966ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncRoleService] Syncing standard role metadata
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace role migrations took 1.3081249999995634ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncAgentService] Syncing standard agent.
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace agent migrations took 0.7992909999993572ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Workspace migrations save took 2.1899590000002718ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Executing pending migrations
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [WorkspaceSyncMetadataService] Execute migrations took 33.817165999999816ms
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [SyncWorkspaceMetadataCommand] Finished synchronizing workspace.
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [SetStandardApplicationNotUninstallableCommand] Checking workspace applications for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [SetStandardApplicationNotUninstallableCommand] Successfully updated workspace application
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [UpgradeCommand] Upgrade for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db completed.
PromiseMemoizer Event: A WorkspaceDataSource for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db is being cleared. Actual pool closure managed by PgPoolSharedService. Not calling dataSource.destroy().
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [UpgradeCommand] Command completed!
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [PgPoolSharedService] pg Pool for key "localhost|5432|postgres||no-ssl" has been closed. Remaining pools: 0
[Nest] 82844  - 11/24/2025, 6:05:13 PM   DEBUG [PgPoolSharedService] Pool[localhost|5432|postgres||no-ssl]: Connection removed from pool
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [PgPoolSharedService] onApplicationShutdown called in PgPoolSharedService
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [PgPoolSharedModule] Shutting down PgPoolSharedModule
[Nest] 82844  - 11/24/2025, 6:05:13 PM     LOG [PgPoolSharedService] onApplicationShutdown called in PgPoolSharedService

———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 NX   Successfully ran target command for project twenty-server and 4 tasks it depends on (7s)

      With additional flags:
        upgrade
```
2025-11-24 17:20:07 +00:00
Baptiste DevessierandGitHub ee761a2594 Keep workflow nodes selected unless side panel is closed (#16029)
This PR no longer relies on Reactflow's `selected` property to determine
whether a node is selected. Instead, we rely on the pre-existing
`workflowSelectedNodeComponentState` state. It makes it easier to to
synchronize what's displayed in the side panel and which node is styled
as being selected.

## Demo - workflows


https://github.com/user-attachments/assets/3848c5f9-df51-48e2-8b9c-f083d25d14ed

## Demo - workflow versions


https://github.com/user-attachments/assets/9ac9ec6c-e6b1-4f24-a817-a7349e1b70d6

## Demo - workflow runs


https://github.com/user-attachments/assets/54f955cf-dacc-43f8-b684-01e8a6c15f3b
2025-11-24 18:02:13 +01:00
Raphaël BosiandGitHub 86aff36035 Fix and improve chart type selection (#16033)
The new version of the side panel is smaller so it introduced a
regression on the chart type selection because there was not enough
space for all the chart types to fit with the label.

This PR removes the label to gain some space and display the chart type
label in a tooltip.

## Before

<img width="834" height="1406" alt="CleanShot 2025-11-24 at 17 33 45@2x"
src="https://github.com/user-attachments/assets/76bbea54-af16-4643-9de6-ab3da6741e11"
/>


## After

### Without disabled charts


https://github.com/user-attachments/assets/74d62b86-e440-41f5-a3e6-c5754940c28e

### With disabled charts


https://github.com/user-attachments/assets/f4ce3a3a-5dee-4f41-8b96-5f671794197d
2025-11-24 16:44:28 +00:00
Charles BochetandGitHub d526b07078 Add ability to discard Information Banner (#16019)
Fixes https://github.com/twentyhq/twenty/issues/14028

<img width="1917" height="965" alt="image"
src="https://github.com/user-attachments/assets/eeb5eab7-2c50-48be-8218-af6052b30777"
/>
2025-11-24 17:34:10 +01:00
42fef6e09b add is operand on number field (#16022)
Co-authored-by: martmull <martmull@hotmail.fr>
2025-11-24 16:04:41 +00:00
Paul RastoinandGitHub a735e3dfef Dirty fix twenty cli ci build order issue (#16024)
# Introduction
- fix twenty-apps hello world deps lockfile 
- improve error response format in application resolver
- fixed tests by adding applicationId back to serverless function
service v2

## New log format
We should have a tmp logs folder where we write the errors so the user
can see the whole of them such as what's done in yarn logs
```ts
    console.log
      ✓ Client generated successfully!

      at GenerateService.generateClient (src/services/generate.service.ts:58:13)

    console.log
      Generated files at: /Users/paulrastoin/ws/twenty/packages/twenty-apps/hello-world/generated

      at GenerateService.generateClient (src/services/generate.service.ts:59:13)

    console.error
       Serverless functions Sync failed: {
        message: 'Multiple validation errors occurred while creating serverless function',
        extensions: {
          code: 'METADATA_VALIDATION_FAILED',
          errors: {
            fieldMetadata: [],
            objectMetadata: [],
            view: [],
            viewField: [],
            viewGroup: [],
            index: [],
            serverlessFunction: [Array],
            cronTrigger: [],
            databaseEventTrigger: [],
            routeTrigger: [],
            viewFilter: []
          },
          summary: {
            invalidViewFilter: 0,
            invalidObjectMetadata: 0,
            invalidView: 0,
            invalidViewField: 0,
            invalidIndex: 0,
            invalidServerlessFunction: 0,
            invalidDatabaseEventTrigger: 0,
            invalidCronTrigger: 0,
            invalidRouteTrigger: 0,
            invalidFieldMetadata: 0,
            invalidViewGroup: 0,
            totalErrors: 0
          },
          message: 'Validation failed for 0 object(s) and 0 field(s)',
          userFriendlyMessage: 'Validation failed for 0 object(s) and 0 field(s)'
        }
      }

      63 |         JSON.stringify(serverlessSyncResult.error, null, 2),
      64 |       );
    > 65 |       console.error(
         |               ^
      66 |         chalk.red(' Serverless functions Sync failed:'),
      67 |         serverlessSyncResult.error,
      68 |       );

      at AppSyncCommand.synchronize (src/commands/app-sync.command.ts:65:15)
      at async AppSyncCommand.execute (src/commands/app-sync.command.ts:21:14)
      at async Object.<anonymous> (src/__tests__/e2e/applications-install-delete-reinstall.e2e-spec.ts:28:22)

```
2025-11-24 15:49:58 +00:00
338e5cf74b i18n - docs translations (#16026)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-24 15:21:05 +01:00
Paul RastoinandGitHub 8299488f21 Fix front data model edition + non nullable workspaceCustom application migration (#16016)
# Introduction
Two things:
- Enforcing non nullable workspace custom application Id for any
workspace
- Fixing front non editable data models following
https://github.com/twentyhq/twenty/pull/15911 that associate any custom
entities to an applicationId. The front was putting everything as
readonly when under an app ( we will have to handle the twenty standard
application in the future too )

## Fallback
### Migration
The non nullable migration will fail when released, that's why it's
being swallowed and re-run in an upgrade command post workspace custom
application creation for those that miss one. Allowing the migration to
pass in the end
The typeorm migration still need to exists for any new workspaces

### GetCurrentUser
In order to dynamically display isReadOnly in data model settings we're
fetching the workspaceCustomApplicationId through the `getCurrentUser`
If not fallback this endpoint would throw until we're handling existing
workspaces that do not have a custom workspace application
The fallback should be removed post release
2025-11-24 13:39:04 +00:00
Raphaël BosiandGitHub 2b80d9e015 [DASHBOARDS] Widget duplication (#15979)
## Widget duplication

- Created a shared component for the option menu shared by the record
page, the dashboards and the workflows
- Fix arrow selection in the option menu in workflows, which wasn't
working
- Scroll to the new widget after creation and open the new widget
settings


https://github.com/user-attachments/assets/47b8dade-44bd-4ba2-a81c-01b09e8718d3
2025-11-24 14:38:18 +01:00
8923d2fa0a i18n - docs translations (#16021)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-24 13:23:07 +01:00
b9355ea5a7 i18n - translations (#16020)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-24 12:32:07 +01:00
85b17a5059 i18n - translations (#16017)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-24 12:01:00 +01:00
Baptiste DevessierandGitHub f2df456588 Refactor Widget components (#15996)
## Demo

All components look the same as before.


https://github.com/user-attachments/assets/ddaf49f7-0e78-4755-af88-19d43b349078

## Catalog of all states of WidgetRenderer

Went really complete on all the states of the component.


https://github.com/user-attachments/assets/303f773a-254d-4469-b904-f5cd9831a823
2025-11-24 11:51:32 +01:00
99d60cd48b Adding system objects to workflow search node (v2) (#15965)
This PR adds support for selecting system objects in the workflow Find
Records action.

The implementation includes extracting duplicated dropdown code into a
reusable component and fixing several code quality issues identified in
previous PR feedback.

All code quality concerns have been addressed: proper TypeScript types,
utility function usage, correct memoization, and improved variable
naming.



https://github.com/user-attachments/assets/8d0bd052-d3dd-4e3e-8379-35bfcb18babc

<img width="514" height="812" alt="CleanShot 2025-11-20 at 16 55 14"
src="https://github.com/user-attachments/assets/4b3617e6-628f-4368-be0c-fc87ef4c4ea9"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-24 11:48:55 +01:00
834d354d46 Command menu follow up improvements (#16007)
Co-authored-by: Devessier <baptiste@devessier.fr>
2025-11-24 11:23:08 +01:00
607dc283d2 i18n - translations (#16014)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-24 11:21:30 +01:00
0e16b939c5 i18n - translations (#16010)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-23 23:20:27 +01:00
0be228fc85 Attest standard object isActive update regression + TDD tests (#15976)
# Introduction
Related https://github.com/twentyhq/twenty/issues/15846

The root cause is that universalIdentifier is still optional in database
and fallbacked when extracted out of database to standardId. But all
`BaseWorkspaceEntity` and `CustomWorkspaceEntity` share the same
standardId for their default standard fields `createdAt` `deletedAt`
resulting in such compare result in dispatcher

```ts
{
  "initialDispatcher": {
    "createdFlatEntityMaps": {
      "byId": {},
      "idByUniversalIdentifier": {},
      "universalIdentifiersByApplicationId": {}
    },
    "deletedFlatEntityMaps": {
      "byId": {},
      "idByUniversalIdentifier": {},
      "universalIdentifiersByApplicationId": {}
    },
    "updatedFlatEntityMaps": {
      "byId": {
        "55e1568c-eb87-4b8a-9f1b-19bbf6042f3e": {
          "updates": [
            {
              "from": "Deletion date",
              "to": "Date when the record was deleted",
              "property": "description"
            },
            {
              "from": "IconCalendarClock",
              "to": "IconCalendarMinus",
              "property": "icon"
            },
            {
              "from": false,
              "to": true,
              "property": "isLabelSyncedWithName"
            },
            {
              "from": null,
              "to": {
                "displayFormat": "RELATIVE"
              },
              "property": "settings"
            }
          ]
        }
      }
    }
  },
  "fromFlatEntity": {
    "universalIdentifier": "20202020-b9a7-48d8-8387-b9a3090a50ec",
    "applicationId": null,
    "id": "9c97c8bf-1f64-463c-915c-f68f41d3cd60",
    "standardId": "20202020-b9a7-48d8-8387-b9a3090a50ec",
    "objectMetadataId": "e9565126-8351-457b-b003-3ea4c6d253bc",
    "type": "DATE_TIME",
    "name": "deletedAt",
    "label": "Deleted at",
    "defaultValue": null,
    "description": "Deletion date",
    "icon": "IconCalendarClock",
    "standardOverrides": null,
    "options": null,
    "settings": null,
    "isCustom": false,
    "isActive": true,
    "isSystem": false,
    "isUIReadOnly": true,
    "isNullable": true,
    "isUnique": false,
    "workspaceId": "20202020-1c25-4d02-bf25-6aeccf7ea419",
    "isLabelSyncedWithName": false,
    "relationTargetFieldMetadataId": null,
    "relationTargetObjectMetadataId": null,
    "morphId": null,
    "createdAt": "2025-11-20T17:28:45.474Z",
    "updatedAt": "2025-11-20T17:28:45.474Z",
    "kanbanAggregateOperationViewIds": [],
    "calendarViewIds": [],
    "viewGroupIds": [],
    "viewFieldIds": [],
    "viewFilterIds": []
  },
  "toFlatEntity": {
    "universalIdentifier": "20202020-b9a7-48d8-8387-b9a3090a50ec",
    "applicationId": null,
    "id": "55e1568c-eb87-4b8a-9f1b-19bbf6042f3e",
    "standardId": "20202020-b9a7-48d8-8387-b9a3090a50ec",
    "objectMetadataId": "37263f48-6858-4d28-a6e1-5f7321e49c24",
    "type": "DATE_TIME",
    "name": "deletedAt",
    "label": "Deleted at",
    "defaultValue": null,
    "description": "Date when the record was deleted",
    "icon": "IconCalendarMinus",
    "standardOverrides": null,
    "options": null,
    "settings": {
      "displayFormat": "RELATIVE"
    },
    "isCustom": false,
    "isActive": true,
    "isSystem": false,
    "isUIReadOnly": true,
    "isNullable": true,
    "isUnique": false,
    "workspaceId": "20202020-1c25-4d02-bf25-6aeccf7ea419",
    "isLabelSyncedWithName": true,
    "relationTargetFieldMetadataId": null,
    "relationTargetObjectMetadataId": null,
    "morphId": null,
    "createdAt": "2025-11-20T17:28:44.267Z",
    "updatedAt": "2025-11-21T17:17:55.057Z",
    "kanbanAggregateOperationViewIds": [],
    "calendarViewIds": [],
    "viewGroupIds": [],
    "viewFieldIds": [],
    "viewFilterIds": []
  }
}
```

## Impact
- This might be corrupting label and description of an other standard
field of an other object
- Race condition on latest universalIdentifier assigned in cache making
the update sometime accurate sometimes not

## Fix
Will be fixed by the in coming work on applicationId and
universalIdentifier as required in database + upgrade command that will
handle retro-comp. ( won't handle description corruption though, should
be anecdotical )
https://github.com/twentyhq/twenty/pull/15911 ( handling this only for
new workspace, retro comp upgrade command will be coming just after )

## PR scope
- Introduce TDD integration tests as failing
- Added unit test to critical methods that might have been involved in
the root cause ( still worth it to keep )

---------

Co-authored-by: guillim <guigloo@msn.com>
2025-11-23 22:37:28 +01:00
Paul RastoinandGitHub f9ab09c404 Metadata api create entity in workspace custom app (#15911)
# Introduction
Cleaner and fewer scope version of
https://github.com/twentyhq/twenty/pull/15745 ( removed sync-metadata
hack through, too ambitious migration and upgrade )

Please note that this PR won't have any interaction with the existing
sync-metadata
Which mean that the sync metadata does not update the standard entities
applicationId and universalIdentifier, and it won't we will deprecate it
on favor of a workspace migration aka twenty-standard app installation

## API Metadata
Any operation going through the api metadata nows automatically scope
the related entity to the workspace custom application instance. (
optionally passing an applicationId to allow current hacky implem of app
sync service )

We need to either ignore the tests or remove the cli status check from
the blocking status badges for a PR to be merged

## New workspace
Already handled in previous
https://github.com/twentyhq/twenty/pull/15625, when a workspace is
created it gets created a twenty standard and custom workspace instance

All his views and permissions will be prefilled to the its twenty
standard app instance with a specific universalIdentifier

## New universalIdentifier
At the contrary as before with standardIds, universalIdentifier are
unique for a given workspace
This means that createdAt field of both object company and opportunity
will have a unique universalIdentifier whereas they share the same
standardId

## FlatApplication
Introduced the flatApplication and cache. Will migrate existing
`MetadataName` to be `SyncableMetadataName` in a following PR

## What's next
Next we will describe a twenty standard app configuration as json that
will be used to generate a workspace migration that will be run instead
of the sync metadata, in a nutshell we aim to deprecated the sync
metadata
So we can standardize any entity to have a non nullable applicationId
and universalIdentifier

## Upgrade command
Introduced an upgrade command that will create a custom workspace
instance for any workspace that do not have one in order to align with
the new behavior when creating a new workspace
2025-11-23 22:35:17 +01:00
4848bc03f3 Update Name of relation fieldMetadata (#15749)
UpdateOne of a Relation that involves a CustomObject, because the
nameSingular needs to be updated in the fieldMetadata
- nameSingular and namePlural must be provided since they are necessary
for morph name computation
  - label sync should be false


Interesting files to look at:

-
packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts

- UPDATE =>
packages/twenty-server/src/engine/metadata-modules/flat-object-metadata/utils/rename-related-morph-field-on-object-names-update.util.ts
( also update relation indexes ) needs v2 refactor to handle field
relation name update
- CREATE =>
packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts
( handle morph instead of previous classic relation )
- DELETE => DONE

Edit:
closes https://github.com/twentyhq/core-team-issues/issues/1897

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-11-23 21:45:30 +01:00
6203b7b3e6 i18n - translations (#16008)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-23 21:21:05 +01:00
neo773andGitHub f2a0b0517a fix ci (#16006) 2025-11-23 21:14:21 +01:00
neo773andGitHub 44c0dcde5b Message channel change 3 fix (#15986) 2025-11-23 20:56:02 +01:00
Lucas BordeauandGitHub 061cc897af Improve record group aggregate query performance (#15828)
This PR is a first step for improving the performance on boards and
table with groups.

It is related to :
https://github.com/twentyhq/core-team-issues/issues/1870

Here we implement only a groupBy query for aggregate values in the group
section.

This also allows to improve the DX of aggregate computing and group by
query creation and parsing.

## Demo 

Main : 



https://github.com/user-attachments/assets/5d2a8077-5322-4928-a551-f03583bcfb87



This PR : 



https://github.com/user-attachments/assets/d0e82b28-72c3-40f0-b5cb-045f1a736ffb



## Aggregate update bug fix

This PR also solves a bug with aggregate update that was already present
on main.

The bug is linked to core views not being updated properly during a
modification of the aggregate operation on a view.

We should probably improve the view lifecycle and state management
because it is a bit too complex right now.

Main : 


https://github.com/user-attachments/assets/10dbfb8b-dfa0-4f21-8698-d222871a43e7

This PR : 


https://github.com/user-attachments/assets/bac41890-5191-4e4c-b82b-19b1039e9ab5

## Miscellaneous 

- Fixed optimistic rendering of group by queries, when adding a new
record, the aggregate recomputes well.

## TODO 

- We might want to improve the optimistic for group by queries that
don't have records nor more than one dimension.
2025-11-23 20:40:23 +01:00
4d55fef874 i18n - docs translations (#16002)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-22 15:20:14 +01:00
e209793e2d i18n - translations (#16001)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-22 13:56:45 +01:00
Charles BochetandGitHub 30e504628c Fix ORM event mixing records in batch updates (#15985)
While investigating the issue a customer was facing, I discovered that
before records and after records could be in different order, making the
orm event and timeline activity engine mix records
2025-11-22 13:16:04 +01:00
b711c11431 message channel change 4 (#15936)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-22 07:49:47 +01:00
martmullandGitHub aa5d30a911 Fix twenty cli (#15997)
As title

fixes "app add" and "app init" commands
adds tests
2025-11-21 19:21:30 +01:00
3b5949ec3c i18n - translations (#15994)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-21 17:21:42 +01:00
a87263e88a i18n - translations (#15993)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-21 16:27:15 +01:00
04b0a65e73 feat: fix Command Menu Side Panel Layout (#15883)
[Figma
Design](https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=81380-344641&t=FpjWNOK2gZuDQQfr-0)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds a side panel layout for the Command Menu, routes modals into a
local container, updates the top bar and context chips, and standardizes
small button sizes.
> 
> - **Command Menu**:
> - **Side Panel Layout**: Introduces `CommandMenuSidePanelLayout` with
animated width, hosts `CommandMenuRouter`, and provides a modal
container via `ModalContainerContext`.
> - **Top Bar**: Redesign (`CommandMenuTopBar`) with back icon, optional
AI sparkles action, compact height
(`COMMAND_MENU_SEARCH_BAR_HEIGHT=40`), and updated placeholder.
> - **Context Chips**: Adds `CommandMenuLastContextChip` and
`CommandMenuRecordInfo`; extends `CommandMenuContextChip` with `page`
prop; updates `CommandMenuContextChipGroups` to render last chip as
record info when applicable.
> - **Container Simplification**: `CommandMenuContainer` simplified to
just provide contexts and `AgentChatProvider`.
> - **Modal System**:
> - Adds `ModalContainerContext` and updates `Modal` to portal into
provided container; `Modal.Backdrop` supports `isInContainer`.
> - Updates usages (e.g., `UserOrMetadataLoader`, `ActionModal`) to
align with new modal behavior.
> - **Page Integration**:
> - Replaces `PageBody` with `CommandMenuSidePanelLayout` in
`RecordShowPage` and `RecordIndexContainerGater`.
> - Removes global `CommandMenuRouter` from `DefaultLayout` (keeps
keyboard shortcuts).
> - **UI/Styling**:
> - Standardizes several buttons to `size="small"` (e.g., command
actions, open record, options, reply, workflow footer).
> - Adjusts `ShowPageSubContainer` styling when rendered inside command
menu.
>   - Storybook tests updated for new placeholder text.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
81fcaa1456. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Devessier <baptiste@devessier.fr>
Co-authored-by: Aman Raj <92664006+araj00@users.noreply.github.com>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
2025-11-21 16:12:41 +01:00
martmullandGitHub 28b8a4f7ec Fix yarn lock (#15992)
as title
2025-11-21 15:53:56 +01:00
martmullandGitHub 445b76fa26 Add uninstall button to application setting (#15988)
As title

<img width="878" height="668" alt="image"
src="https://github.com/user-attachments/assets/b0c9ae1e-036f-4bdd-9bd2-a2a37c2e3b99"
/>
2025-11-21 14:45:07 +00:00
martmullandGitHub 1fa9c45879 Fix twenty sdk (#15991)
As title
2025-11-21 14:28:15 +00:00
Raphaël BosiandGitHub 0b241cc805 Fix widget resize handles intersecting with top bar buttons (#15990)
Fixes https://github.com/twentyhq/core-team-issues/issues/1881 and
https://github.com/twentyhq/twenty/issues/15946



https://github.com/user-attachments/assets/da89f5b3-e977-4a5d-8e8f-4a903eaa7db6
2025-11-21 15:14:15 +01:00
WeikoandGitHub a21d58f43d Add entitySchemas to workspace context and cache (#15966) 2025-11-21 15:07:46 +01:00
Félix MalfaitandGitHub f77fcdcc63 Disable telemetry in tests (#15989)
As per title
2025-11-21 14:32:02 +01:00
Félix MalfaitandGitHub d85785e380 Twenty self hosting app (#15987)
App to manage telemetry/billing (twenty for twenty!)
2025-11-21 14:10:51 +01:00
nitinandGitHub 793119b117 part 1 of filter/sort drill down from charts (#15983)
This Pr handles basic navigation on bar/slice click to the chart's
source objects index view
2025-11-21 12:54:36 +00:00
Baptiste DevessierandGitHub 3e187b4ce3 [Page Layouts] Focus specific tabs on mobile and side panel (#15984)
## On mobile


https://github.com/user-attachments/assets/4a8017b2-56a9-4759-bc18-8d99fed9f80a

## In side panel


https://github.com/user-attachments/assets/f36f0827-699a-4f76-8e84-a8ceaeb71396

## Dashboards

Untouched, but keep working.


https://github.com/user-attachments/assets/fe583f80-ea8d-453e-95ea-6b99175d1899

## Other Record Page Layouts

Untouched, but keep working.


https://github.com/user-attachments/assets/c64f731f-5d28-4585-8cb5-c3940fb1ab6f
2025-11-21 13:39:17 +01:00
WeikoandGitHub 0a2d42e79f Implement workspace cache storage (#15962)
## Context
Implementing a single service managing all the cache scoped to a
workspace, this will be dynamically injected as a WorkspaceContext in
the app during a request lifetime (ingested by the future global
datasource for example).

Usage:

```typescript
this.globalWorkspaceOrmManager.executeInWorkspaceContext(
        authContext,
        async () => {
           // Everything here will have access to a workspaceContext, containing all the cache data + a ready to use datasource with workspace scoped metadata, permissions, feature flags, etc...
           // Internally will call loadWorkspaceContext
        }
```
Note: executeInWorkspaceContext will probably be owned by a higher level
service later and not only the ORM.

```typescript
  private async loadWorkspaceContext(
    authContext: WorkspaceAuthContext,
  ): Promise<WorkspaceContext> {
    const workspaceId = authContext.workspace.id;

    const cache =
      await this.workspaceContextCacheService.get<WorkspaceContextData>(
        workspaceId,
        [
          'objectMetadataMaps',
          'metadataVersion',
          'featureFlagsMap',
          'permissionsPerRoleId',
        ],
      );

    return {
      authContext,
      objectMetadataMaps: cache.objectMetadataMaps,
      metadataVersion: cache.metadataVersion,
      featureFlagsMap: cache.featureFlagsMap,
      permissionsPerRoleId: cache.permissionsPerRoleId,
    };
  }
  ```
  
  The cache retrieval strategy is as followed:
```
- Check if there is an ongoing promise fetching data from the cache =>
return the promise.
- Check in the local cache entry if lastCheckedAt has expired. If not,
return as it is without querying redis.
- Check in redis the cache entry hash and compare with local cache entry
hash, if they are the same return the local cache entry data
- Check in redis the cache entry data, if it's there return it and store
it into the local cache entry data and update local cache entry hash. If
it's not there recompute the data by querying the DB and update both
redis and local cache
```
2025-11-21 12:44:24 +01:00
a95fff82cc i18n - docs translations (#15981)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-21 11:15:42 +01:00
Abdullah.andGitHub 991bb6dbbf fix: crash in HeaderParser in dicer. (#15963)
Resolves [Dependabot Alert
74](https://github.com/twentyhq/twenty/security/dependabot/74).

Upgraded `graphql-upload` from `13.0.0` to `16.0.2`. Type exports
changed. API remains the same.

Tested the following upload flows:
- profile picture
- workspace logo
- rich text editor (image, video, file)
- record profile picture
- file associated to record.

They all work as intended, nothing breaks.
2025-11-21 11:09:47 +01:00
neo773andGitHub f82325b66b handle HTTP 410,404 in GmailMessagesImportErrorHandler (#15969)
Noticed this in prod, we currently return `undefined` instead of
handling it.
2025-11-21 11:06:21 +01:00
neo773andGitHub dc3e30b115 message channel change 5 (#15964) 2025-11-21 11:05:12 +01:00
31ca2a46c5 i18n - translations (#15980)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-21 10:56:57 +01:00
a3c0d274ea Updated by extension (#15937)
Working updated by extension which shows the workspace member behind the
newest change

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-11-21 10:28:44 +01:00
fdb4e4ef10 [DASHBOARDS] Use a time scale when the primary axis is a date on the Bar Chart (#15932)
Closes https://github.com/twentyhq/core-team-issues/issues/1891

Create empty buckets according to the date granularity

Video QA:


https://github.com/user-attachments/assets/86c0f817-35b3-4bab-b093-d11491684b82

Note: We would also need to create empty buckets for cyclic
granularities (DAY_OF_THE_WEEK, MONTH_OF_THE_YEAR, QUARTER_OF_THE_YEAR).
TODO:
- Always order the cyclic granularities Monday -> Sunday (take
firstDayOfTheWeek into account), January -> December, Q1 -> Q4. For now
they are returned by the backend in alphabetical order, which doesn't
make much sense
- Remove the translation into the user's locale of these granularities
from the backend because otherwise we can't reconstruct the missing days
or month in the frontend since they will be translated

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-21 10:24:19 +01:00
c737042209 i18n - translations (#15967)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-20 19:22:24 +01:00
8d021d2719 i18n - docs translations (#15945)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-20 18:33:17 +01:00
Félix MalfaitandGitHub a281f2a773 feat: add configurable response format for AI agents (text/JSON) (#15953)
## Summary
This PR adds configurable response format support for AI agents,
allowing them to return either plain text or structured JSON data based
on a defined schema.

## Key Features

### 1. Agent Response Format Configuration
- Added `AgentResponseFormat` type supporting:
  - `text`: Returns plain text responses (default)
  - `json`: Returns structured JSON based on defined schema
- New `AgentResponseSchema` type moved to `twenty-shared/ai` for sharing
between frontend/backend

### 2. Settings UI
- New `SettingsAgentResponseFormat` component for configuring response
format
- Visual schema builder for defining JSON output structure
- Real-time validation and preview
- Integrated into agent settings tab

### 3. Workflow Integration
- AI Agent workflow action automatically uses agent's configured
response format
- Output schema dynamically generated from agent's response format
- Workflow variable picker shows structured fields for JSON responses
- Backward compatible with existing text-only agents

### 4. Backend Implementation
- Added `convertAgentSchemaToZod` utility to validate JSON responses
- Agent executor service handles both text and JSON generation
- Automatic agent creation/cloning when adding AI agent steps to
workflows
- Unique agent naming with conflict resolution

### 5. Database Migration
- Migration `1763622159656-update-agent-response-format.ts` 
- Sets default `responseFormat` to `{"type":"text"}` for existing agents
- Updated all standard agents with proper response format

## Changes by Module

### Frontend (`twenty-front`)
- 🆕 `AgentResponseFormat` type
- 🆕 `SettingsAgentResponseFormat` component
- ✏️ Updated `WorkflowEditActionAiAgent` to support response format
configuration
- 🗑️ Removed deprecated `useAiAgentOutputSchema` hook and
`AiAgentOutputSchema` type

### Backend (`twenty-server`)
- 🆕 `AgentResponseFormat` type in agent entity
- 🆕 `convertAgentSchemaToZod` utility for schema validation
- ✏️ Updated `AiAgentExecutorService` to handle both text and JSON
generation
- ✏️ Updated `WorkflowSchemaWorkspaceService` to generate output schema
from agent config
- ✏️ Enhanced `WorkflowVersionStepOperationsWorkspaceService` with agent
creation/cloning
- 🆕 Agent naming constants for conflict resolution

### Shared (`twenty-shared`)
- 🆕 `AgentResponseSchema` type
- 🆕 `ModelConfiguration` type moved to shared package
- Updated exports in `ai/index.ts`

## Code Quality
- Removed useless comments following code style guidelines
- All linter checks passed
- Type-safe implementation with proper TypeScript types

## Testing
-  Database migration tested
-  Agent creation/cloning in workflows verified
-  Response format switching (text ↔ JSON) validated
-  Backward compatibility with existing agents confirmed

## Migration Notes
- Existing agents will have `responseFormat: {type: 'text'}` set
automatically
- No breaking changes - all existing functionality preserved
- Agents can be updated to use JSON format through settings UI
2025-11-20 18:32:44 +01:00
neo773andGitHub 5476879f77 Handle Microsoft calendar sync cursor error (#15938)
Resolves https://twenty-v7.sentry.io/issues/6567295627
2025-11-20 16:32:44 +01:00
Paul RastoinandGitHub e5255df1a1 Fix and refactor relation field name collision validation (#15920)
# Introduction
Fixes https://github.com/twentyhq/private-issues/issues/371
We weren't strictly validating relation field collision on join column
name availability of the target field object

## Refactor
Extracted morph or relation specific condition out of the common flat
field metadata name validate availability to be located in the dedicated
morph or relation flat field validator

## Tests
Added two tests, ONE_TO_MANY and MANY_TO_ONE in order to cover the use
case
2025-11-20 15:10:35 +00:00
Baptiste DevessierandGitHub 9c6d8330df Bring back companies focused actions (#15961)
We want to release the readonly mode of record page layouts before the
edit mode. We will think about adding actions related to page layout
edition later.


https://github.com/user-attachments/assets/2c2213d2-80b8-4d6f-b4bf-e023ac9d2906

Closes https://github.com/twentyhq/core-team-issues/issues/1818
2025-11-20 15:53:34 +01:00
Abdullah.andGitHub c7783de930 Introduce Dependabot config for SOC2 compliance. (#15956) 2025-11-20 15:24:26 +01:00
c7aa59491b Fix merge button (#15899)
Fixes https://github.com/twentyhq/private-issues/issues/362

**How to reproduce**
Link a person that has a duplicate to an opportunity. (you can create a
duplicate by giving two people the same linkedin link).
Open the opportunity record from opportunity table. 
Click on the related person (in "Point of contact").
In front of "Duplicates", click on the merge button (two arrows becoming
one).
You should here see an empty "Merge preview" and an error when clicking
"First" tab.

**Issue**
The issue is that CommandMenuMergeRecordPage is getting the referenced
objectMetadataItem from useContextStoreObjectMetadataItemOrThrow without
an instance id. contextStoreObjectMetadataItem is still "opportunity" as
it should be, being on an opportunity view.
So further down it attempts to display the record page according the
label identifier field from opportunity, which is a text field, "name",
and it breaks because the record is actually a person for who the "name"
field is not a text but a full_name type.

**Fix**
I suggested a fix that offers the possibility to find the referenced
objectMetadataItem from the MergeRecords instanceId. But I still gave
flexibility to avoid having to set that state everytime we open the
merge tab, by falling back to the default
contextStoreObjectMetadataItem. (this is used when we merge records from
ticking two records from a view and open the command menu).
Im not sure this is the best option. Open to suggestions !

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-20 13:58:40 +01:00
martmullandGitHub 6607fe0504 Fix wrong empty string formatting (#15949)
As title, solves this kind of issues
https://twentyfortwenty.twenty.com/object/workflowRun/d6aca50e-68ba-4715-8835-ea22bd44fb88

Solves null currencyDisplay when null currencyCode and null amountMicros

### Before
<img width="147" height="81" alt="image"
src="https://github.com/user-attachments/assets/d250d65e-b984-43f4-ad67-1397a684cf6a"
/>

 ### After
 
<img width="128" height="74" alt="image"
src="https://github.com/user-attachments/assets/4f9c9d80-f8bb-495a-9be0-ecfb984ded81"
/>
2025-11-20 12:11:16 +01:00
CopilotGitHubcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>Devessier
a1bfab82df Remove VITE_DISABLE_ESLINT_CHECKER environment variable (#15943)
The `VITE_DISABLE_ESLINT_CHECKER` environment variable is removed from
the codebase. ESLint checker no longer runs during Vite builds
(equivalent to the previous `VITE_DISABLE_ESLINT_CHECKER=true`
behavior).

**Configuration**
- Removed from `.env.example` (active and commented lines)
- Removed from `vite.config.ts` destructuring and conditional logic
- Removed from build scripts in `package.json` and `nx.json`

**Code change in vite.config.ts:**
```diff
- if (VITE_DISABLE_ESLINT_CHECKER !== 'true') {
-   checkers['eslint'] = {
-     lintCommand: 'eslint ../../packages/twenty-front --max-warnings 0',
-     useFlatConfig: true,
-   };
- }
```

**Documentation**
- Updated main English troubleshooting guide to remove references to the
variable
- Translated documentation files are intentionally not modified and will
be handled by a separate workflow

> [!NOTE]
> ESLint will not run in the background via Vite's checker plugin.
Developers will need to run `npx nx lint twenty-front` manually or rely
on their IDE's ESLint extension for real-time feedback on open files.

Created from VS Code via the <a
href="https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github">GitHub
Pull Request</a> extension.

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>

> Your job is to delete everything related to
VITE_DISABLE_ESLINT_CHECKER in the codebase.
> 
> We mention this env var in documentation: drop the content talking
about it.
> 
> We use it in the vite config: drop the check and keep the code paths
that used to run when `VITE_DISABLE_ESLINT_CHECKER=true`.
> 
> User has selected text in file packages/twenty-front/.env.example from
3:1 to 3:28


</details>

Created from VS Code via the [GitHub Pull
Request](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github)
extension.

<!-- START COPILOT CODING AGENT TIPS -->
---

 Let Copilot coding agent [set things up for
you](https://github.com/twentyhq/twenty/issues/new?title=+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
2025-11-20 11:38:43 +01:00
98e44ed92a feat: use relative and absolute dates in email (#15827)
Closes #15322

Used `formatToHumanReadableDate` to show absolute dates, rather than
only relative dates. When the date is clicked, it flips between relative
and absolute. The click on the date, doesn't show or hide the email
body. Attaching a recording of the same below.



https://github.com/user-attachments/assets/77adcd3e-8efe-4af9-a57e-6317c93bcf22



https://github.com/user-attachments/assets/0731de02-60bb-42b1-a28c-55a94cff24b8

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-20 10:09:44 +00:00
EtienneandGitHub 8998f3bd84 Fix int tests - update snapshots (#15944)
because of integration tests not working yesterday,
[PR](https://github.com/twentyhq/twenty/pull/15931) has been merged with
not updated snapshots
2025-11-20 10:05:49 +00:00
Raphaël BosiandGitHub 3c3d837cb7 Introduce primary actions (#15826)
- These actions are displayed in the accent color
- Added new context store state
`contextStoreIsPageInEditModeComponentState`
- Reverted the order in which the actions are displayed (the first
action should appear to the right of the top bar action menu)



https://github.com/user-attachments/assets/3a0769cf-61ed-4619-8c4d-e3a01765b63c
2025-11-20 10:57:33 +01:00
martmullandGitHub 3190ca5b9e 1858 extensibility create relation metadata decorator in thwenty sdkapplications (#15907)
as title

First PR 
I will update the twenty-cli in another PR
2025-11-20 10:22:42 +01:00
Paul RastoinandGitHub 89d166ece6 fix(server): ssr front (#15934) 2025-11-19 19:16:46 +01:00
EtienneandGitHub 674ddbd525 Fix raw json validation (#15931)
Before validation in common layer, stringified json were accepted in raw
json field. Fix regression

related to
https://discord.com/channels/1130383047699738754/1130383048173682821/1440723288090218636
2025-11-19 19:05:02 +01:00
Aman RajandGitHub 0223851620 Fixed eslint warnings on changed files (#15928) 2025-11-19 17:13:07 +01:00
neo773andGitHub 67846c05bf revert PR 12884 (#15922)
this PR never really addressed the root cause which was later addressed
in the auth refactor PR so reverting this as it's also causing some
errors.
2025-11-19 14:28:00 +01:00
Félix MalfaitandGitHub bf638c3a4e Fix file controller route parameter extraction (#15924)
## Problem
When accessing file URLs like `/files/attachment/{token}/{filename}`,
the server was returning 500 errors with no logs. The issue was that the
route pattern `*path/:filename` was not properly extracting parameters,
causing `request.params[0]` to be undefined.

## Solution
- Changed route from `@Get('*path/:filename')` to
`@Get(':folder/:token/:filename')` for explicit parameter extraction
- Simplified `extractFileInfoFromRequest` to use named route parameters
directly instead of complex path parsing
- Removed unnecessary logging that was added during debugging
- Added test to verify route parameters are correctly extracted and
passed to FileService

## Testing
- Added unit test that verifies folder, token, and filename parameters
are correctly passed to the service
- Test will catch any future regressions where route parameters are not
properly extracted
2025-11-19 14:12:34 +01:00
ca29357d37 i18n - docs translations (#15923)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-19 13:22:56 +01:00
9ad3b7be84 i18n - translations (#15919)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-19 11:36:58 +01:00
Félix MalfaitandGitHub 783fe8d387 Agent role edition (#15914)
## 🐛 Issues Fixed

### 1. Role Editing Not Working for New Agents
When creating a new agent and then creating a role for it, the role
permissions appeared as non-editable. This was caused by:
- In create mode, `agentId = ''` (empty string from `useParams`)
- Empty string is **falsy** but `isDefined('')` returns **true**
- This caused incorrect behavior in role exclusivity checks and API
calls

### 2. Missing Role Data Loading
The agent form wasn't loading role data needed for permission editing
because it was missing the `SettingsRolesQueryEffect` component.

### 3. Navigation Conflicts
The `useSaveDraftRoleToDB` hook contained navigation logic that caused
conflicts when used from different contexts (role detail page vs agent
form).

### 4. Linting Errors
Unused `useIcons` import in `SettingsAgentRoleTab.tsx`.

---

## 🔧 Changes Made

### Agent Role Tab (`SettingsAgentRoleTab.tsx`)
-  Use `isNonEmptyString(agentId)` to validate agentId (follows
codebase patterns)
-  Improved role exclusivity logic to handle both create and edit
modes:
  - **Edit mode**: Role must be assigned exclusively to this agent
  - **Create mode**: Role must not be assigned to anyone yet
-  Only call `assignRoleToAgent` when a valid agentId exists
-  Pass `undefined` instead of empty string for `fromAgentId` prop

### Role Hook (`useSaveDraftRoleToDB.ts`)
-  Removed navigation logic from the hook (better separation of
concerns)
-  Removed `useNavigateSettings` and `SettingsPath` dependencies
-  Hook now only handles data persistence, not navigation

### Role Component (`SettingsRole.tsx`)
-  Added navigation after successful role creation in create mode
-  Navigation now handled by the component using the hook

### Agent Form (`SettingsAgentForm.tsx`)
-  Added `SettingsRolesQueryEffect` to ensure role data is loaded
-  Agent form handles its own navigation after save

---

##  Testing Scenarios

All these scenarios now work correctly:
1.  Create new agent → Create role → Edit permissions → Save agent
2.  Edit existing agent → Create role → Edit permissions → Save
3.  Edit existing agent → Try to edit shared role (shows warning
message)
4.  Navigate to object-level permissions from agent form with proper
breadcrumbs

---

## 📝 Technical Details

### Root Cause Analysis
The main issue was that empty string was being treated differently in
different checks:
- `agentId &&` → evaluates to `false` (empty string is falsy)
- `isDefined(agentId)` → returns `true` (empty string is defined)

This inconsistency caused the role to appear as non-editable and
attempted invalid API calls.

### Solution
Used `isNonEmptyString()` from `@sniptt/guards` which properly checks
both that the value is defined AND not empty, following codebase
conventions.

---

## 🎯 Impact

- Fixes critical bug preventing role permission configuration for new
agents
- Improves code quality with better separation of concerns
- Makes navigation logic more predictable and maintainable
- Follows codebase patterns and guidelines
2025-11-19 11:26:05 +01:00
92fb4c708b i18n - docs translations (#15917)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-19 11:21:41 +01:00
4b0d1cd848 Fixed immediate UI update after Enter on single-item fields (#15825)
Previously, single-item fields `maxItemCount: 1` didn’t show updated
values after pressing `Enter` the UI only refreshed on click outside.
This happened because the items list was hidden while
`shouldAutoEditSingleItem` remained true.

This PR updates the render condition to also check `!isInputDisplayed`,
ensuring the items list re-renders immediately after editing.

**Result:** Instant UI updates on Enter with no impact on multi-item
fields.

Fixes #15792

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-19 11:15:17 +01:00
nitinandGitHub eab123f999 Custom data point labels for line chart (#15793)
https://github.com/user-attachments/assets/a3074292-acc7-4117-add4-8b3f8d00673e
2025-11-19 11:00:30 +01:00
Raphaël BosiandGitHub 5b52ac992e [DASHBOARDS] Tab duplication (#15906)
Closes https://github.com/twentyhq/core-team-issues/issues/1878

- Allow tab duplication
- Add autofocus on the tiltle input upon the creation and duplication of
tabs and the creation of widgets
- Fix a bug where cancelling the edition while on a new tab, by
resetting the active tab id if it's not in the persisted tabs


https://github.com/user-attachments/assets/a4dc2f0b-1a56-406a-bde7-cca17f9cdbc1
2025-11-19 10:57:37 +01:00
d4e85376ea i18n - docs translations (#15913)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-18 19:22:08 +01:00
bcb097256b fix-15838 (#15898)
I know you did this change in order to make the frontend faster and less
resource eating. However it broke this optimistic rendering part
@lucasbordeau.

I suggest this quick fix, but I am open to a sharper one as well

Fixes https://github.com/twentyhq/twenty/issues/15838

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-18 18:49:18 +01:00
f6cd51ba97 feat: Support custom fields in calendar event detail panel (#15853)
## Overview
This PR refactors the `CalendarEventDetails` component to dynamically
display both standard and custom fields added via the metadata API,
instead of using a hardcoded field list.

## Changes
- Replaced hardcoded `fieldsToDisplay` array with dynamic field fetching
using `useFieldListFieldMetadataItems` hook
- Split fields into `standardFields` (maintaining original order) and
`customFields`
- Introduced `renderField` helper function to eliminate code duplication
- Custom fields now automatically appear at the bottom of the detail
panel after standard fields
- Maintained exact field order and all existing functionality including
participant response status display

## Technical Details
- Uses existing `useFieldListFieldMetadataItems` pattern already
established in the codebase
- Standard field order explicitly defined: startsAt, endsAt,
conferenceLink, location, description
- Participant response status (Yes/Maybe/No) correctly positioned
between first 2 and last 3 standard fields
- All fields respect permissions and visibility settings from metadata

## Testing
-  Verified all standard fields display in correct order
-  Added custom field `mycustomfieldtest` via metadata API - displays
correctly at bottom
-  Participant responses (Yes/Maybe/No) render correctly with avatars
-  Event title, creation date, and event chip display properly
-  Canceled event styling (strikethrough) works
-  No console errors or regressions detected
-  Read-only behavior maintained (calendar events sync from external
sources)

## Screenshots

<img width="1401" height="746" alt="CleanShot 2025-11-17 at 11 23 57"
src="https://github.com/user-attachments/assets/3d967ec5-6d31-4fc3-b971-c73ea521c87d"
/>


## Related
This enables users to extend calendar events with custom metadata fields
that will automatically display in the UI without code changes.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-18 18:11:07 +01:00
6fa75e1360 i18n - translations (#15908)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-18 18:01:56 +01:00
Abdullah.andGitHub 9c61b625a1 Remove the redundant nx/js package from twenty-server since root has it. (#15905)
There was an extra definition of @nx/js inside twenty-server, which was
not recognized during upgrade by the CLI. This caused two versions of
@nx/js in the repo - 22.0.3 from root and 21.3.11 from the twenty-server
package.

Removed the one inside twenty-server to maintain a single source of
truth.
2025-11-18 17:41:45 +01:00
MarieandGitHub 5bb4abc23d Add optional limit variable to groupBy queries (#15885)
Closes https://github.com/twentyhq/core-team-issues/issues/1600.

Two remarks 
- This `limit` variable does not reduce postgre's work at it still needs
to scan the whole table. It did not seem possible to me to optimize this
as we cannot foresee which dimensions will be used by the user, and an
optimization could only result from an index on the dimension(s) (e.g.:
group companies by addressCity limit 50 can be optimized if we have an
index on companies.addressCity + we had a default orderBy on
adressCity). But this will still optimize the FE which at the moment
receives all groups and truncates the result.
- I have not done the work on the FE as the addition of limit is a
breaking change, and will break until the workspaces' schema is rebuilt,
so we need to flush the cache. I think this could be acceptable as the
feature is in the lab but I preferred not doing it yet as it would have
no impact since in the BE I added a default limit to 50 groups, and I
expect more FE work will be done to allow the user to choose their own
limit
2025-11-18 17:25:33 +01:00
Ali IlmanandGitHub be7c2ad40a [ENHANCEMENT] [ACTIVITY-SUMMARY] Improvisations post-hacktoberfest (#15882)
## Background
Team Comfortably Summed had submitted Activity Summary for Twenty's
Hacktoberfest. This is a follow-up PR post-Hacktoberfest.

## Changes
### Purpose
>_What is the objective?_

To improve the code based on human and bot comments from the initial
Hacktoberfest PR, and to improve the robustness of task completion
calculation.
>_Are we solving a problem or making necessary changes to support an
existing and / or a new feature?_

Making changes to improve existing features.
### Summary
> _Are there files we can ignore?_

None.
> _Please provide a high-level summary of the changes._

- Corrects `README.md` by removing irrelevant commands and unnecessary
configuration notes
- Updates `people-creation-summariser.ts`
- Replaces requesting of company for each person by including `depth=1`
as query parameter in GET /people request as suggested by Martin Muller
– link to comment:
[link](https://github.com/twentyhq/twenty/pull/15510#discussion_r2486019035)
- Updates `senders.ts`
  - Renames `formattedMesage` to `formattedMessage`
- Updates `task-creation-summariser.ts`
- Improves calculation of completed task percentage by relying only on
list of completed tasks and total list of tasks
- The initial implementation includes relying on pending tasks and
pending overdue tasks which can result in undesired calculation outcome
2025-11-18 17:23:11 +01:00
e02c24bd3a i18n - docs translations (#15904)
Created by Github action

---------

Co-authored-by: Abdul Rahman <ar5438376@gmail.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-18 17:21:48 +01:00
neo773andGitHub 46149cdb14 add case for calendar revoked refresh token (#15837) 2025-11-18 17:14:31 +01:00
Abdullah.andGitHub 222feb90b4 fix: update glob version to 11.1.0 (#15884)
Some Glob CLI related alerts were generated last night. I believe
they're safe to dismiss since I do not expect us to use the Glob CLI in
production environment, and those alerts do not impact the API, but
still updating the dependency version just in case.

Not sure if this would resolve all/any of the alerts since glob is a
dependency for many other dependencies, so a good number of dependency
variants are pulled in.

The alert that confirms it's just a CLI related vulnerability:
[Dependabot Alert
307](https://github.com/twentyhq/twenty/security/dependabot/307)
2025-11-18 17:12:53 +01:00
neo773andGitHub cbb5bce500 expose imap username field (#15866)
Had an edge with a customer where they had a custom username.
2025-11-18 17:12:02 +01:00
neo773andGitHub 347e855b1f update default message folder import policy to ALL_FOLDERS (#15858) 2025-11-18 16:59:15 +01:00
EtienneandGitHub db48059bea Fix test (#15895) 2025-11-18 16:55:54 +01:00
Thomas des FrancsandGitHub c38f34df26 Release 1.11.0 (#15900)
## Release 1.11.0

This release includes:

- Unlisted Views

Changelog file:
`packages/twenty-website/src/content/releases/1.11.0.mdx`
Release date: 2025-11-18
2025-11-18 16:51:12 +01:00
martmullandGitHub f131a86cc5 Update lock parameters (#15901)
as title
2025-11-18 15:40:42 +00:00
martmullandGitHub ee648197df Set TTL >> max await + increase max await from 1s to 2s (#15892)
- set TTL >> max await
- increase max await from 1s to 2s
2025-11-18 16:25:04 +01:00
Abdullah.andGitHub 47ea2b53d3 fix: bump up js-yaml patch number inside fireflies app (#15890)
Resolves the last remaining js-yaml alert: [Dependabot Alert
304](https://github.com/twentyhq/twenty/security/dependabot/304).

Updates version of js-yaml from 3.14.1 to 3.14.2.
2025-11-18 16:03:56 +01:00
14d3866439 fix: hotkey visibility in buttons with blue accent (#15764)
Closes #15728

## Problem
The `color` of `ButtonHotKeys` was set to `theme.border.color.blue` when
the button accent was blue. This led to poor visibility of the hotkey.

## Solution
The `color` is now set to `GRAY_SCALE_LIGHT.gray7`

## Screenshots
### Before
<img width="278" height="54" alt="image"
src="https://github.com/user-attachments/assets/7dd2c8a4-1230-4b57-9a1d-62564ab15337"
/>
<img width="280" height="52" alt="image"
src="https://github.com/user-attachments/assets/21cc62fb-e1eb-47ce-925c-3658389d24d8"
/>


### After
<img width="274" height="54" alt="image"
src="https://github.com/user-attachments/assets/cfbed222-a807-4af2-ab11-839ef5274186"
/>
<img width="275" height="52" alt="image"
src="https://github.com/user-attachments/assets/602274d8-3af6-4de8-9504-2cb0fe30d5dc"
/>

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-18 14:56:00 +00:00
martmullandGitHub bbe104c27b Fix asset path (#15888)
As title
Fix workflow code step creation error
2025-11-18 13:55:34 +01:00
Abdullah.andGitHub 7d74e17bfc fix: js-yaml has prototype pollution in merge (#15886)
Resolves [Dependabot Alert
309](https://github.com/twentyhq/twenty/security/dependabot/309) and
maybe also a few others.

Bumped up the version for js-yaml to 4.1.1 and 3.14.2 across transitive
dependencies using `yarn up js-yaml --recursive`.
2025-11-18 13:45:15 +01:00
Abdullah.andGitHub d6d7f1bb20 fix: koa related dependabot alerts (#15868)
Resolves [Dependabot Alert
256](https://github.com/twentyhq/twenty/security/dependabot/256) and
[Dependabot Alert
296](https://github.com/twentyhq/twenty/security/dependabot/296).

This is a major bump for `nx` and related packages. Used the CLI to run
nx migrations as recommended by the maintainers. Tested building,
testing and linting packages after resetting the daemon, and did not
come across a breaking issue.
2025-11-18 13:44:45 +01:00
nitinandGitHub 8434610f18 seperate v1 and v2 seeds, make groupMode to add default in case its not provided through api but primary groupBy is present (#15815)
Context - 
- refactoring v1 and v2 seeds to test v2 dashboard flag both on and off
Right now, the db reset command fails if the feature flag is off

- whenever there is a groupBy field -- we should add a default groupMode
- we already do that on the front -- but implementing the same on server
so that api users get the same response

This is also the reason why the second seed on dashboards lags a lot --
because on that particular dashboard's widget -- we set groupBy but no
groupMode (in seeding util) -- and the effect of limiting the bars to
fifty runs depending on the groupMode
2025-11-18 11:29:12 +00:00
Baptiste DevessierandGitHub 6209ba539b Add icons to Record Page Layout tabs (#15871)
## Demo


https://github.com/user-attachments/assets/71ce776a-8d59-4b2c-8579-185fdd749f8f

Closes https://github.com/twentyhq/core-team-issues/issues/1812
2025-11-18 12:25:18 +01:00
76cc07a5f7 Revert x2 - Common - Field validation (#15491) (#15879)
Revert https://github.com/twentyhq/twenty/pull/15821

Should not have been reverted. Conflicting with this
[PR](https://github.com/twentyhq/twenty/pull/15742),
[reverted](https://github.com/twentyhq/twenty/pull/15875)

Co-authored-by: Weiko <corentin@twenty.com>
2025-11-18 12:04:00 +01:00
GuillimandGitHub 9e425ee684 preventing the last item to be unselected (#15873)
Fix https://github.com/twentyhq/twenty/issues/15867
2025-11-18 11:17:49 +01:00
f86c5e78b1 fix(workflow): UUID filter in "Search Records" action (#15817)
## Summary
- add a regression test that reproduces the workflow "Search Records →
ID is <UUID>" failure (issue #15067 / #15746)
- adjust `turnRecordFilterIntoRecordGqlOperationFilter` so UUID filters
fall back to the literal value when no `recordIdsForUuid` context is
provided, always emitting an `in` clause

## Testing
- npx nx test twenty-shared --
--testPathPattern=computeRecordGqlOperationFilter.test.ts
--coverage=false
- Manual: workflow "Search Records" with filter "ID is <UUID>" now
returns the correct record

Fixes #15067
Fixes #15746

---------

Co-authored-by: remi <remi@labox-apps.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-18 10:14:38 +00:00
Baptiste DevessierandGitHub e0d1f74648 Page layout conditional display (#15802)
- Allow widgets to be hidden based on device's type conditions: desktop
or mobile
- Create two widgets for rich text fields on tasks and notes. One widget
is displayed below fields on mobile (and in the right drawer); the other
is displayed on a separate tab on desktop
- In read mode, hide tabs if they contain no visible widgets. If there
is no tab left to display, display at least the first one with no
widgets.
- In edit mode, display all tabs and all widgets.

## Demo


https://github.com/user-attachments/assets/65ef1261-3902-4432-a420-48983b763b2c

Closes https://github.com/twentyhq/core-team-issues/issues/1811
2025-11-18 10:35:38 +01:00
martmullandGitHub d0d90735cb Revert "refactor: Simplify CRUD services to leverage Common API (#157… (#15875)
This reverts commit 11e07f90d2.
2025-11-18 09:44:15 +01:00
Félix MalfaitandGitHub 0fa2a4524a feat: Add filter button to objects table and enable system objects access (#15856)
## Summary
This PR replaces the Active/Inactive accordion sections with a modern
filter dropdown button and enables full access to system objects in
advanced mode.

## Changes

### UI Improvements
-  Replaced accordion sections with a filter button dropdown (matching
the design pattern from the Group filter)
-  Added 'Deactivated' toggle filter (hidden by default, uses
IconArchive)
-  Added 'System objects' toggle filter (only visible in advanced mode,
uses IconSettings)
-  Fixed search input width to properly fill available space
-  Proper button sizing and alignment

### System Objects Support
-  Made system objects visible when 'System objects' filter is toggled
on
-  System objects are now fully clickable and accessible
-  Updated object detail page to support system objects
-  Updated field creation/edit pages to support system objects
-  System objects can now have custom fields added

### Architecture
-  Implemented scalable filter architecture using a single filtered
list
-  Easy to add more filters in the future (e.g., show remote objects)
-  All filters work independently and can be combined

## Testing
- [x] Tested deactivated objects toggle
- [x] Tested system objects toggle (only shows in advanced mode)
- [x] Tested clicking on system objects
- [x] Tested adding custom fields to system objects
- [x] No linter errors

## Screenshots
See attached screenshots in the conversation for the new filter UI.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds a filter dropdown to the Settings Objects table (incl.
deactivated/system toggles), enables system objects across
settings/field flows, seeds core views (workspace members, messages,
threads, calendar events), and adds actions for Workspace Members.
> 
> - **Settings UI**
> - **Objects Table**: Replaces Active/Inactive sections with a single
filterable list and dropdown (`Deactivated`, `System objects` in
advanced mode); updates props to `objectMetadataItems` and removes
accordion sections.
> - **Search/UX**: Search input fills available space; inactive rows
show activation/delete menu; active rows remain navigable.
> - **Pages Updated**: `SettingsObjects`,
`SettingsApplicationDetailContentTab` switch to new table API; object
detail and new-field flows use `findObjectMetadataItemByNamePlural`
(works with system objects).
> - **Action Menu**
> - **Workspace Members**: Adds `WORKSPACE_MEMBERS_ACTIONS_CONFIG` with
"Manage members in settings" action; wired into `getActionConfig` for
`WorkspaceMember`.
> - **Server (Core Views Seed)**
> - Adds default views: `workspaceMembersAllView`, `messagesAllView`,
`messageThreadsAllView`, `calendarEventsAllView`; included in
`prefillCoreViews`.
> - Marks workflow entities as system (`WorkflowRun`,
`WorkflowVersion`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6a2856df85. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-17 19:10:19 +01:00
Abdullah.andGitHub 60ed9b53f4 fix: vercel’s AI SDK's filetype whitelists can be bypassed when uploading files (#15874)
Resolves [Dependabot Alert
301](https://github.com/twentyhq/twenty/security/dependabot/301).

Locked the version of "ai" at 5.0.52 in order to stop it from bumping to
5.0.93 directly when the ^ is introduced since it breaks the code across
multiple files.
2025-11-17 18:03:45 +00:00
Félix MalfaitandGitHub 19ca93b954 Fix auth connection (#15869)
Better to do auth this way than in module
2025-11-17 18:12:48 +01:00
8d7ee47ec5 fix: custom-cron-ui (#15786)
Fixes #14723 

### Summary
Fixes a UI while creating a custom CRON

### Changes Made
- updated `WorkflowEditTriggerCronForm.tsx` to use the predefined
`FormSelectFieldInput.tsx` instead of using `Select.tsx`
- added `hint` prop to `FormSelectFieldInput.tsx`
- updated styling for showing `Upcoming execution time`
- added conditional render for `Schedule` and `Upcoming Execution Time` 
- `Schedule`  section is not rendered in Custom Cron

### Steps to Reproduce (Before Fix)
1. Navigate to - /object/workflow/xxxx
2. Try adding a new Trigger
3. Set Trigger Interval to Cron (Custom)


### Before 

![Screenshot 2025-11-13 at 4 00
29 PM](https://github.com/user-attachments/assets/f85ab0fa-cb71-4257-9659-10e1404f17ed)


### After

![Screenshot 2025-11-13 at 4 00
55 PM](https://github.com/user-attachments/assets/db1d54ef-e5d5-42e2-9de5-c1f91f46088e)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-17 18:03:41 +01:00
2a44bde848 Dynamic grql api wrapper on application sync (#15791)
# Introduction

Important note: for the moment testing this locally will require some
hack due to latest twenty-sdk not being published.
You will need to build twenty-cli and `cd packages/twenty-cli && yarn
link`
To finally sync the app in your app folder as `cd app-folder && twenty
app sync`

close https://github.com/twentyhq/core-team-issues/issues/1863

In this PR is introduced the generate sdk programmatic call to
[genql](https://genql.dev/) exposed in a `client` barrel of `twenty-sdk`
located in this package as there's high chances that will add a codegen
layer above it at some point ?

The cli calls this method after a sync application and writes a client
in a generated folder. It will make a graql introspection query on the
whole workspace. We should later improve that and only filter by current
applicationId and its dependencies ( when twenty-standard application is
introduced )

Fully typesafe ( input, output, filters etc ) auto-completed client

## Hello-world app serverless refactor

<img width="2480" height="1326" alt="image"
src="https://github.com/user-attachments/assets/b18ea372-b21d-4560-8fbc-1dc348427a95"
/>

---------

Co-authored-by: martmull <martmull@hotmail.fr>
2025-11-17 14:46:59 +01:00
Paul RastoinandGitHub a39efeb1ab [BREAKING_CHANGE/GRAPHQL/OBJECT_METADATA_CREATE_ONE] Remove object/fields/view-fields v1 implementation (#15823)
# Introduction
Remove the v2 feature flag for view-field field-metadata and
object-metadata metadata entities

## Some details
- Disabled nestjs-query for object metadata creation and explicitly
calling it
- removed all v1 integration tests files

## Remarks
Not remove v2 referencing in both filenaming right now will handle that
globally later

## Breaking change
Due to object metadata resolver createOne standardization had to rename
the input from `CreateObjectInput` to `CreateOneObjectInput`
2025-11-17 10:55:19 +01:00
Abdullah.andGitHub c1dcda6475 fix: cookie accepts cookie name, path, and domain with out of bounds characters (#15845)
Resolves [Dependabot Alert
143](https://github.com/twentyhq/twenty/security/dependabot/143).

Used `yarn up @bundled-es-modules/cookie --recursive` to move from
version `2.0.0` to `2.0.1` so that the underlying cookie dependency
version moves from `0.5.0` to `0.7.2`.
2025-11-17 07:36:14 +00:00
Abdullah.andGitHub 321a2bec53 fix: babel has inefficient regexp complexity in generated code with .replace when transpiling named capturing groups (#15844)
Resolves [Dependabot Alert
199](https://github.com/twentyhq/twenty/security/dependabot/199) and
[Dependabot Alert
200](https://github.com/twentyhq/twenty/security/dependabot/200).

Used `yarn up @babel/runtime --recursive` and `yarn up
@babel/runtime-corejs3 --recursive` to move from `7.26.7` to `7.28.4`.

Changelogs do not list any breaking changes when moving between minor
versions, only improvements. The parent dependencies also allow minor
version upgrades.
2025-11-17 08:17:25 +01:00
Abdullah.andGitHub 7a68aa7f48 fix: playwright downloads and installs browsers without verifying the authenticity of the SSL certificate (#15843)
Resolves [Dependabot Alert
293](https://github.com/twentyhq/twenty/security/dependabot/293).

Updates the playwright version used to `1.56.1`. The alert could have
also been ignored since the playwright download only happens in CI and
local environments, not the production environment. However, it's an
easy fix instead of just ignoring the alert.
2025-11-17 08:16:56 +01:00
Paul RastoinandGitHub 48031a7ce2 Runner v2 on cascade delete_field/object + refactor workspace deletion side effect (#15830)
# Introduction
While removing the v1 https://github.com/twentyhq/twenty/pull/15823 I've
encountered the method `objectMetadataService.deleteObjectsMetadata`
that I didn't wanted to migrate as it is and if it's not challenging its
existence legitimacy.

## Motivations
In a nutshell on a workspace deletion object metadata and field metadata
cascading deletion is correclty handled
But that's not the case for all of a workspaces entities ( roles,
workspaceMigrations ) I suspect that we did not defined the foreignKey
explicitly through `typeorm`

## Battle testing v2
I still decided to give a try to a complex operation in the v2 such as a
workspace all object metadata deletion.
Spoiler it failed due to object being interdependent between them and
not being topologically sorted ( morph relation can introduce circular
dep anw ).
Note: Even after removing the delete field on delete object aggregator
we end up with an equivalent circular dep error which an object and its
field metadata identifier connection.

## Elegant `DEFERRED` and `DEFERRABLE` foreign keys
The most safe, low level solution would be to make all field relations
deferrable and start the runner transaction as deferred. But this
requires a quite invasive migration of existing FK

## On cascade solution
I've opted for the quick fix, on object or field deletion spread
cacasde.
It's pretty safe as the builder priorly validates the deletion and and
its related entities integrity
Only for both field and object deletion action types in v2 runner

## Integration coverage
Added a test that will scan a new workspace database core schema tables
and expect now result after workspace deletion through its only user
deletion
2025-11-16 22:03:50 +01:00
Abdullah.andGitHub baa1a1e52f fix: babel vulnerable to arbitrary code execution when compiling specifically crafted malicious code (#15840)
Resolves [Dependabot Alert
95](https://github.com/twentyhq/twenty/security/dependabot/95) - babel
vulnerable to arbitrary code execution when compiling specifically
crafted malicious code.

These were the few options we had for a direct drop-in replacement.
- [x-var](https://www.npmjs.com/package/x-var?activeTab=readme)
- [cross-let](https://www.npmjs.com/package/cross-let)
- [cross-var-no-babel](https://www.npmjs.com/package/cross-var-no-babel)

x-var has the most weekly downloads among the three and it is also the
most actively maintained fork of the original cross-var package that
introduced the vulnerability. There is no syntax difference per the
documentation, but I do not have a windows machine to test.

`cross-var-no-babel` offers the most minimal changes, but is also
abandoned without a public-facing repo.
2025-11-16 20:12:25 +01:00
Félix MalfaitandGitHub 5dfb66917c Upgrade NestJS from 10.x to 11.x (#15836)
## Overview
This PR upgrades all NestJS dependencies from version 10.x to 11.x,
following the [official migration
guide](https://docs.nestjs.com/migration-guide). This builds on top of
the v9 to v10 upgrade completed in PR #15835.

## Changes

### Dependencies Updated
**Core packages (10.x → 11.x):**
- `@nestjs/common`: 10.4.16 → 11.0.8
- `@nestjs/core`: 10.4.16 → 11.0.8
- `@nestjs/platform-express`: 10.4.16 → 11.0.8
- `@nestjs/config`: 3.2.3 → 3.3.0
- `@nestjs/passport`: 10.0.3 → 11.0.0
- `@nestjs/axios`: 3.0.2 → 3.1.2
- `@nestjs/schedule`: ^3.0.0 → ^4.1.1
- `@nestjs/serve-static`: 4.0.2 → 5.0.1
- `@nestjs/cache-manager`: ^2.2.1 → ^2.3.0
- `@nestjs/jwt`: 10.2.0 → 11.0.0
- `@nestjs/typeorm`: 10.0.2 → 11.0.0
- `@nestjs/terminus`: 11.0.0 (already on v11)
- `@nestjs/event-emitter`: 2.1.0 (compatible)

**DevDependencies:**
- `@nestjs/testing`: ^10.4.16 → ^11.0.8
- `@nestjs/schematics`: ^10.1.0 → ^11.0.2
- `@nestjs/cli`: 10.3.0 → 11.0.0

### Code Changes
**Fixed: TwentyConfigModule conditional imports**
- Updated `TwentyConfigModule.forRoot()` to use spread operator for
conditional imports
- Fixes TypeScript error with NestJS 11's stricter DynamicModule type
checking

**Cleanup: Removed unused package**
- Removed `@revertdotdev/revert-react` (not being used anywhere in the
codebase)

## Breaking Changes Addressed

### 1.  Reflector Type Inference
- **Impact**: None - codebase only uses `reflector.get()` method
- **Analysis**: Does not use `getAllAndMerge()` or `getAllAndOverride()`
(the methods with breaking changes)
- **Files reviewed**: feature-flag.guard.ts,
message-queue-metadata.accessor.ts,
workspace-query-hook-metadata.accessor.ts

### 2.  Lifecycle Hooks Execution Order
- **Change**: Termination hooks (`OnModuleDestroy`,
`BeforeApplicationShutdown`, `OnApplicationShutdown`) now execute in
REVERSE order
- **Analysis**: Reviewed all lifecycle hook implementations
  - Redis client cleanup
  - Database connection cleanup (GlobalWorkspaceDataSource)
  - BullMQ queue/worker cleanup
  - Cache storage cleanup
- **Result**: Dependency order is safe - services using connections
clean up before the connections themselves

### 3.  Middleware Registration Order
- **Change**: Global middleware now executes first regardless of import
order
- **Analysis**: Middleware is not registered as global, so execution
order remains consistent
- **Files reviewed**: app.module.ts, middleware.module.ts

## Testing

All tests passing and build successful:

**Unit Tests (283+ tests):**
-  Health module: 38 tests passed
-  Auth module: 115 tests passed (passport v11 integration)
-  REST API: 90 tests passed (middleware and express platform)
-  Feature flags: 17 tests passed (Reflector usage)
-  Workspace: 23 tests passed

**Build & Quality:**
-  Type checking: Passed
-  Linting: Passed
-  Build: 3,683 files compiled successfully

## Verification

Tested critical NestJS functionality:
-  Authentication & Security (JWT, OAuth, guards)
-  HTTP Platform (Express integration, REST endpoints)
-  Dependency Injection (Services, factories, providers)
-  Cache Management (Redis with @nestjs/cache-manager)
-  GraphQL (Query runners, resolvers)
-  Configuration (Environment config)
-  Scheduling (Cron jobs with @nestjs/schedule v4)
-  Lifecycle Hooks (Module initialization and cleanup)
-  Reflector (Metadata reflection in guards)

## Related PRs
- #15835 - Upgrade NestJS from 9.x to 10.x (completed)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Upgrades NestJS to v11 and updates routing patterns, auth strategies,
GraphQL schema options, and build/dist paths (scripts, Docker, Nx,
migrations, assets), plus enables Devtools in development.
> 
> - **Backend (NestJS 11 upgrade)**:
> - Bump `@nestjs/*` packages (core, platform-express, jwt, passport,
typeorm, serve-static, schedule, cli/testing/schematics) to v11.
> - Update REST/route-trigger/file controllers to new wildcard syntax
(`*path`).
> - Refactor OAuth (Google/Microsoft) and SAML strategies (abstract base
+ explicit `validate`); minor typings.
>   - Enable `DevtoolsModule` in development.
> - **GraphQL**:
> - Add `buildSchemaOptions.orphanedTypes` for client-config types; keep
Yoga/Sentry setup.
> - **Build/Runtime & Config**:
> - Standardize dist layout (remove `src` in paths): update scripts,
Docker `CMD`, Nx `project.json`, render scripts, TypeORM migration
paths, asset resolution.
> - Adjust `nest-cli.json` (watchOptions, asset globs, migrations
outDir, monorepo/root).
> - Improve config module imports (spread conditional); tsconfig
excludes `node_modules`.
>   - Minor Nx default: `start` target caching disabled.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1139fd85a9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-16 18:20:06 +01:00
Félix MalfaitandGitHub a2a7ff8b4b Upgrade NestJS from 9.x to 10.x (#15835)
## Overview
This PR upgrades all NestJS dependencies from version 9.x to 10.x,
following the [official migration
guide](https://docs.nestjs.com/v10/migration-guide). This is the first
step before upgrading to NestJS 11.x in a future PR.

## Changes

### Dependencies Updated
- `@nestjs/common`: 9.4.3 → 10.4.16
- `@nestjs/core`: 9.4.3 → 10.4.16
- `@nestjs/passport`: 9.0.3 → 10.0.3
- `@nestjs/platform-express`: 9.4.3 → 10.4.16
- `@nestjs/config`: 2.3.4 → 3.2.3
- `@nestjs/event-emitter`: 2.0.4 → 2.1.0
- `@nestjs/testing`: ^9.0.0 → ^10.4.16
- `@nestjs/schematics`: ^9.0.0 → ^10.1.0

### Code Changes
- Fixed `CacheModuleOptions` import from `@nestjs/common` to
`@nestjs/cache-manager` in cache-storage.module-factory.ts

## Breaking Changes Addressed
 **CacheModule Migration**: Already using `@nestjs/cache-manager`
package
 **TypeScript Version**: Using 5.9.2 (requires 4.8+)  
 **Node.js Version**: Using 24.5.0 (requires 16+)  
 **Deprecated APIs**: All v9 deprecations removed in v10 - standard
patterns in use

## Testing
All tests passing and build successful:
-  Health module: 38 tests passed
-  Auth module: 115 tests passed (critical - uses @nestjs/passport)
-  Admin panel: 30 tests passed
-  REST API: 90 tests passed (uses @nestjs/platform-express)
-  Feature flags: 17 tests passed
-  Workspace: 23 tests passed
-  GraphQL query runner: 17 tests passed
-  **Total: 330+ tests passing**
-  Build: 3,683 files compiled successfully
-  Type checking: Passed
-  Linting: Passed

## Verification
Tested critical NestJS functionality:
- Authentication & Security (JWT, OAuth, guards)
- HTTP Platform (Express integration, REST endpoints)
- Dependency Injection (Services, factories, providers)
- Cache Management (Redis with @nestjs/cache-manager)
- GraphQL (Query runners, resolvers)
- Configuration (Environment config)
- Event Emitters (Event-driven architecture)

## Next Steps
This upgrade positions the codebase for the next upgrade to NestJS 11.x,
which will be handled in a separate PR.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Upgrades NestJS to v10, fixes cache module import, and narrows CI
GraphQL generation diff to generated directories.
> 
> - **Backend**
> - **Dependencies**: Upgrade `@nestjs/common`, `@nestjs/core`,
`@nestjs/platform-express`, `@nestjs/passport`, `@nestjs/config`,
`@nestjs/event-emitter`, `@nestjs/testing`, and `@nestjs/schematics` to
v10-compatible versions in `packages/twenty-server/package.json`.
> - **Code**: Update `CacheModuleOptions` import to
`@nestjs/cache-manager` in
`src/engine/core-modules/cache-storage/cache-storage.module-factory.ts`.
> - **CI**
> - **GraphQL**: Restrict schema change detection to
`packages/twenty-front/src/generated` and
`packages/twenty-front/src/generated-metadata` in
`.github/workflows/ci-server.yaml`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f621230fcf. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-15 23:06:13 +01:00
Abdul RahmanandGitHub c0bae491e1 docs: localize navigation tabs and groups for supported locales (#15811) 2025-11-14 22:03:54 +01:00
Baptiste DevessierandGitHub 54f74b2a5a Properly interpret advanced filters boolean values in workflows (#15829) 2025-11-14 19:01:53 +01:00
martmullandGitHub f13c36234f Fix workspace-member-id missing from database events (#15819)
As title
2025-11-14 14:03:49 +00:00
martmullandGitHub b3d85623e6 Remove unexisting mock value (#15822)
removes when signup

<img width="975" height="324" alt="image"
src="https://github.com/user-attachments/assets/93184788-81b9-4a7d-b572-d3bce594444f"
/>
2025-11-14 13:56:01 +00:00
martmullandGitHub 867422627c Revert "Common - Field validation (#15491)" (#15821)
This reverts commit 261cba40ef.
2025-11-14 13:47:22 +01:00
martmullandGitHub df58f4102e Fix typo in command (#15818)
as title
2025-11-14 10:42:26 +00:00
WeikoandGitHub 4dd6edb35a Fix authContext missing in ALS WorkspaceContext for global datasource (#15810)
Fixes https://github.com/twentyhq/twenty/issues/15809

## Context
We recently introduced a global datasource now consuming workspace
context from ALS store however the authContext was missing (only the
workspaceId was there) which "broke" event emission, now missing the
workspaceMemberId

This PR adds the missing authContext so we can access from anywhere in
the datasource. We are still passing it as a parameters on repository
level for legacy but in theory we should be able to remove it from
everywhere and consume the context

<img width="929" height="253" alt="Screenshot 2025-11-13 at 18 58 16"
src="https://github.com/user-attachments/assets/3e04f264-95e6-4831-94f3-fc01603f19bd"
/>
2025-11-14 10:59:15 +01:00
Abdul RahmanandGitHub bff079d3b5 Fix AI chat scroll behavior (#15686) 2025-11-14 01:20:25 +01:00
Lucas BordeauandGitHub 9d43058e50 Fixed hovering of kanban cards (#15808)
This PR fixes the record inline cells that disappeared on board card due
to recent refactors.
2025-11-13 17:49:52 +00:00
WeikoandGitHub 998365457e Improve infer deletion from entities (#15807)
## Context
inferDeletionFromEntities only accepts a set of keys for each entities
that needs deletion. This could be error-prone if tmr we want to add a
new side effect and forget to add the entity when in practice you want
to delete all entities that are in the fromToAllFlatEntityMaps (this is
the case for applications for example)
2025-11-13 18:18:27 +01:00
Raphaël BosiandGitHub 56b3a0e8a5 Fix REST API Delete and Destroy (#15806)
Fixes https://github.com/twentyhq/twenty/issues/15801
2025-11-13 18:14:32 +01:00
9bc5486d0d i18n - translations (#15803)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-13 17:12:39 +01:00
Paul RastoinandGitHub 0fdc7ba834 Twenty-shared tests parses decorator (#15765)
## Introduction
Since we've moved some class validator instances from twenty-server to
twenty-shared tests are red because they do not know how to parse
decorators declarations

We've fixed this by explicitly installing `class-validator` in
`twenty-shared` and configuring jest swc accordingly

## Twenty-server class validator patch
I don't even know if that's something we need anymore
Seems to be a patch either fixing or introducing credit card and phone
number validation
Would prefer discussing the need or not to either before merging this as
it could introduce regression at runtime:
- Centralize the patch to be consumed in both `twenty-server` and
`twenty-shared`
- Remove the patch

We should also document every patch motivations we do as it's quite
though to iterate over a such huge one
2025-11-13 16:06:04 +00:00
8cadd00d34 i18n - translations (#15799)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-13 16:34:00 +01:00
Félix MalfaitandGitHub cd5d0f9eac Introduce agent hints to reduce context bloat (#15763)
Introducing a new pattern that should reduce token consumption by 90%
for the most common use-cases
2025-11-13 16:15:01 +01:00
261cba40ef Common - Field validation (#15491)
Closes : https://github.com/twentyhq/core-team-issues/issues/1622

To do in other PR : 
- Add migration command for non nullable text, raw_json & array fields
- Add null transformation

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-11-13 15:45:35 +01:00
Félix MalfaitandGitHub f6ed1e8295 Merge data navigator and manipulator agents (#15761)
Merge data manipulator and navigator agents
2025-11-13 15:25:52 +01:00
Charles BochetandGitHub 9bbe0e7f8e Add message folders control in seed by default (#15789)
As per title
2025-11-13 15:09:13 +01:00
martmullandGitHub ab967bf81f Add profile to twenty-cli authentication (#15778)
As title
Eg: 
<img width="641" height="45" alt="image"
src="https://github.com/user-attachments/assets/0ac159db-ebcf-4c21-af1b-b089ee3b39f8"
/>

Not breaking
2025-11-13 15:08:53 +01:00
0cab2b49fc (breaking change) Allow users with a single workspace to update their email. (#15736)
- Users with a single workspace are allowed to update their email across
`core.user` and `workspace_xyz.workspaceMember`.
- The latter happens asynchronously (built it like this for non-blocking
with multiple workspaces), but since we restrict the email update
functionality to a single user, we can also update the email in
workspaceMember synchronously - I left asynchronous there to receive
feedback on whether we should move to synchronous or not.
- Merged main and resolved conflicts to ensure we use the
`SettingsPermissionGuard` and the updated `workspace.service.ts` code.

One edge-case that I was trying to communicate on Discord: 

Say that an admin is a member of multiple workspaces. Therefore, they
can allow roles with PROFILE_INFORMATION permission to update their
email.

<p align="center">
<img width="553" height="115" alt="image"
src="https://github.com/user-attachments/assets/80382b1f-a9e3-4dac-b606-c2defeb2c330"
/>
</p>

However, since the admin is part of multiple workspaces, he/she cannot
even update own email - the field stays disabled, leading to some
confusion.

<p align="center">
<img width="545" height="255" alt="image"
src="https://github.com/user-attachments/assets/5e6d27db-c9a8-4d5e-9ab6-65c77beae5b4"
/>
</p>

However, the workspace can have another member with admin role or some
other role that has PROFILE_INFORMATION permission flag. That user will
be and should be allowed to update email, so we cannot hide `email` from
dropdown options.

<p align="center">
<img width="585" height="283" alt="image"
src="https://github.com/user-attachments/assets/a670d3ac-cf48-4865-a425-b909093d8420"
/>
</p>

The behavior is fine imo, just a little confusing for members with more
than one workspace.

I have also tested the flow by signing up to YC workspace with my org
google account (twenty.com), then changing email to my personal address.
- After changing, I need to login using Google with my personal account
to access YC workspace again.
- If I login using Google with org google account (twenty.com), a new
user account is created.

This behavior is consistent with Notion and Linear. 

Finally, as for the verification of email, the user is asked to verify
email while they're logged in, but just in case they logout without
verifying, the next login would force them to verify their email in the
email/password flow.

However, for Social/SSO, they must verify before they logout or else
they'd have to contact support for assistance. I have not looked into
how to show verification screen while logging in via Social/SSO yet, but
if that's something critical for completeness here, I shall revisit it.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-11-13 15:00:02 +01:00
Lucas BordeauandGitHub dd0601ab6f Fix phone not empty filter (#15790)
This PR fixes the filter on not empty phones.

We can end up with phone numbers that only have a country code, but it
makes no sense to consider this special edge case "not empty".

If we have no phone number, then it's empty, so this PR applies this
particular use case for NOT EMPTY filter on phone fields.

Fixes https://github.com/twentyhq/twenty/issues/15638
2025-11-13 13:38:56 +00:00
3ef9be6622 message channel change #3 (#15757)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-13 14:12:20 +01:00
GuillimandGitHub a3b78f080b removing the picture of morph in the lab (#15787)
cleaning unsued image following a nitpick from another PR
2025-11-13 13:35:27 +01:00
Félix MalfaitandGitHub f9c61833ec Add debug info in AI chat (#15758)
## 🐛 Critical Bug Fix

### Cost Calculation Error (1000x undercharge)
- **Fixed**: Cost conversion utility was calculating credits at 1/1000th
of actual value
- **Before**: `cents * 10` 
- **After**: `(cents / 100) * DOLLAR_TO_CREDIT_MULTIPLIER` 
- **Impact**: Users were being undercharged by 1000x
  - Example: 0.75 cents should = 7,500 credits
  - Bug calculated it as 7.5 credits

---

## 🎯 Code Centralization & DRY

### Unified Cost Calculation
- Centralized all cost conversions to use `convertCentsToBillingCredits`
utility
- Refactored 3 different implementations into 1 single source of truth
- Files updated:
  - `ai-billing.service.ts`
  - `agent-streaming.service.ts` (2 usages)

**Before** (multiple implementations):
```typescript
// Wrong implementation
const credits = cents * 10;

// Verbose implementation  
const costInDollars = costInCents / 100;
const creditsUsed = Math.round(costInDollars * DOLLAR_TO_CREDIT_MULTIPLIER);
```

**After** (unified):
```typescript
const creditsUsed = Math.round(convertCentsToBillingCredits(costInCents));
```

---

##  UI Component Refactoring

### RoutingDebugDisplay.tsx
- **Reduced from 118 lines to 34 lines** (71% reduction)
- Extracted `renderTimingRow` helper to eliminate 15 repetitive JSX
blocks
- Added `formatTokenBreakdown` helper for token display logic
- Much easier to add new debug metrics

**Before**: 15 nearly-identical blocks of repetitive JSX  
**After**: Clean, DRY implementation with reusable helpers

---

## 🧹 Code Quality Improvements

### Removed Debug Code
- Removed `console.log` accidentally left in `RoutingStatusDisplay.tsx`

### Cleaned Up Comments (18+ removed)
Removed redundant comments that stated the obvious:
-  "Calculate routing cost if we have token usage"
-  "Send the updated routing status with execution metrics to the
client"
-  "Count tool calls in the response"
-  "AI SDK's LanguageModelUsage uses inputTokens/outputTokens"
- And 14+ more...

Kept meaningful comments:
-  "Timing is optional, ignore errors" (explains catch block)
-  Type definition grouping comments

---

## 📊 Statistics

**Files Modified**: 10
- `convert-cents-to-billing-credits.util.ts` (fixed formula)
- `ai-billing.service.ts` (use centralized utility)
- `agent-streaming.service.ts` (use utility, remove comments)
- `agent-execution.service.ts` (remove comments)
- `ai-router.service.ts` (remove comments)
- `RoutingStatusDisplay.tsx` (remove debug code)
- `RoutingDebugDisplay.tsx` (major refactor) 
- `isDebugModeState.ts` (new file)
- `DataMessagePart.ts` (type extensions)
- `useClientConfig.ts` (debug mode support)

**Impact**:
- Lines removed: ~130 (redundant code + comments)
- Lines added: ~45 (helper functions)
- **Net reduction**: ~85 lines
- **Bug fixes**: 1 critical (1000x cost error)
- **Centralizations**: 3 locations now using shared utility
- **Major refactors**: 1 UI component (71% reduction)

---

##  Verification

-  All linter checks pass
-  All tests pass (`ai-billing.service.spec.ts` verified)
-  No `any` types in affected code
-  No TODO/FIXME markers

---

## 🎯 Principles Applied

1.  **Fix Root Causes, Not Symptoms** - Fixed utility function, then
used it everywhere
2.  **DRY (Don't Repeat Yourself)** - Centralized cost calculation and
UI rendering
3.  **Single Source of Truth** - One place for cost conversion formula
4.  **Code as Documentation** - Removed comments that repeated what
code says
5.  **Composability** - Created reusable helper functions
6.  **Type Safety** - Maintained strict typing throughout
2025-11-13 13:34:46 +01:00
nitinandGitHub fddac24e7f connect line chart to backend (#15657)
https://github.com/user-attachments/assets/b797c5a8-32a8-4d3e-9fb1-7541d107a19f

optimizations:
before: 


https://github.com/user-attachments/assets/bf45a3f1-5f89-40c1-9ce4-c2d912b77d63


after:


https://github.com/user-attachments/assets/61bfd603-7b63-4695-8ae8-68fe7d3bfea0
2025-11-13 11:35:08 +00:00
eee35e5e25 Surface record selection limit in Workflow Manual Trigger and in Search Node (#15785)
fixes https://github.com/twentyhq/twenty/issues/15704

Take over: https://github.com/twentyhq/twenty/pull/15738

based on [KhademOHAli1](https://github.com/KhademOHAli1) work

---------

Co-authored-by: Ali Khadem <ali.kh@pitant.de>
2025-11-13 12:11:48 +01:00
GuillimandGitHub 0389fcf00d removing feature flag IS_MORPH_RELATION_ENABLED (#15783)
releasing the morph feature for all workspaces
2025-11-13 12:03:25 +01:00
Raphaël BosiandGitHub cb759aa22e Fix concurrent page layout edition bug (#15740)
This PR fixes a bug which could happen if two people were editing a page
layout at the same time.
If one person deletes a widget or a tab and saves first, and the second
person saves after but doesn't delete this widget or tab, an error is
raised.

This is because, in the backend, a diff is computed to know which tab or
widget to create, update or delete. But the logic was maid without
considering soft deletion. So, when the second person saves, the diff
tries to create the widget or tab which had been soft deleted by the
first use. Since they have the same id, a duplicate primary key error is
raised.

Now we always consider that the last user to save has the truth. So we
restore the tab/widget and update it.
2025-11-13 12:01:11 +01:00
Lucas BordeauandGitHub a453d53656 Fix Snackbar crashing the whole app (#15774)
This PR fixes a crash of the app when a Snackbar tries to render an
object.

<img width="3002" height="754" alt="image"
src="https://github.com/user-attachments/assets/988f97eb-5c8a-44f8-ac8e-e2953b872bac"
/>

What happened : the backend sent a MessageDescriptor in
`extensions.userFriendlyMessage` while it should have sent a translated
string.

But it is a problem that the Snackbar can end up rendering objects and
crashing the whole app because it is a the highest level in the tree.

So this PR hardens many points to avoid future bugs : 
- Sanitize what is rendered by the Snackbar to avoid any crash
- Translate any MessageDescriptor object that could end up in the
frontend
- Fix the places in the backend where a MessageDescriptor wasn't
translated and sent directly to the frontend in
`use-graphql-error-handler.hook.ts`

Fixes https://github.com/twentyhq/twenty/issues/15685
Fixes https://github.com/twentyhq/core-team-issues/issues/1869
2025-11-13 12:01:06 +01:00
b82d38bb13 fix(ui): layout-shift-on-tasks (#15775)
Fixes #12090 

### Summary
Fixes a UI layout shift issue in table rows in Tasks page, where bottom
borders appeared inconsistently across rows.
The problem occurred because `shouldDisplayBorderBottom` conditionally
applied the bottom border, which caused slight height differences
between rows and visual "jumping" when rendering focused styling.

### Changes Made
- Ensured consistent `border-bottom` rendering
- Removed conditional rendering prop to always display bottom border

### Steps to Reproduce (Before Fix)
1. Navigate to - /objects/tasks?viewId=xxxx
2. Interact with row elements
3. Notice a slight layout shift when first row is active/focused


### Before 

https://github.com/user-attachments/assets/ab95db5d-0922-4460-a086-a03f58375824

### After


https://github.com/user-attachments/assets/a6b4d50c-b6f0-456b-90d4-fc3f0cde42bc

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-13 10:56:18 +00:00
ec7e49c8bb fix: minor color changes (#15616)
Closes #15597

The `color` of `OnBoardingModalCircularIcon` was set to `gray`. Now it
is set to `inverted` and it is displayed properly. I couldn't figure out
how to reach the onboarding screen, so I created a temporary path and
rendered the element there to verify the changes. Attaching screenshots
of the same.
<img width="398" height="393" alt="Screenshot from 2025-11-05 00-11-05"
src="https://github.com/user-attachments/assets/25efc790-92a3-42b5-8298-5128a3f1a466"
/>

<img width="398" height="418" alt="Screenshot from 2025-11-05 00-10-32"
src="https://github.com/user-attachments/assets/af52c695-4b01-40e9-a873-39d491c633cc"
/>

Additionally, a border has been added to the color picker icons.
<img width="573" height="383" alt="Screenshot from 2025-11-05 00-12-23"
src="https://github.com/user-attachments/assets/03d967aa-8c6f-4dfd-be3d-a2e16fe12b9a"
/>

I noticed that the dropdown after clicking on the icon also renders a
bunch of colors. Do let me know if these need the same border as well.
<img width="571" height="366" alt="Screenshot from 2025-11-05 00-12-37"
src="https://github.com/user-attachments/assets/a13bf253-6765-4d7a-9f0f-17cb7375a515"
/>

---------

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
2025-11-13 10:00:28 +00:00
BOHEUSandGitHub 3c58ed233b Add missing color changes in workflow steps with no data (#14967)
Fixes #14888
2025-11-13 10:39:38 +01:00
martmullandGitHub 1b308a7b74 Fix can't save empty env variables values (#15773) 2025-11-12 15:48:55 +01:00
Félix MalfaitandGitHub 09e89334c6 Fix Tool permissionn guard issue (#15770)
Fix a critical issue on the permission guard for tools which led to
users being denied access when they should have had access
2025-11-12 11:51:54 +01:00
martmullandGitHub f4663038b6 Rename sdk utils (#15769)
Follow ups
2025-11-12 11:20:59 +01:00
Raphaël BosiandGitHub ea56586766 Fix horizontal bar chart spacing between ticks (#15702)
This PR fixes a bug where the spacing between ticks on the Y axis was
adjusted according to the width of the widget where it should have been
adjusted according to the height. Same for the X axis.

**Before**:
Works for the vertical layout but not for the horizontal layout


https://github.com/user-attachments/assets/f0b94103-1ba6-4dbe-bbc6-c47541c1b5fa


**After**:
Works for both


https://github.com/user-attachments/assets/165faada-2943-4e05-92d6-a31def569500
2025-11-12 10:19:32 +00:00
065923d724 feat: Add Workflow duplicate step (#15622)
## Description

- This PR address issue
https://github.com/twentyhq/core-team-issues/issues/1800
- Added workflow duplicate option in workflow sidepanel
- Introduced DuplicateWorkflow.ts mutuation
- Updated graphql generated metadata with new duplicate type




## Visual Appearanc

<img width="1792" height="1031" alt="Screenshot 2025-11-07 at 4 46
22 PM"
src="https://github.com/user-attachments/assets/d75f99df-ae18-4b41-a5f4-21c50010cdbc"
/>


https://github.com/user-attachments/assets/3dbf73cf-f4dd-484c-94a3-29577cfbac25

---------

Co-authored-by: Devessier <baptiste@devessier.fr>
2025-11-12 10:53:25 +01:00
12e2820715 fix(docs): Use content instead of props for Card titles to enable translation (#15756)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-11-12 10:44:04 +01:00
martmullandGitHub 534a2bf647 Rename sdk utils (#15766)
As title
2025-11-12 10:42:55 +01:00
fcf66bc881 update Notes & Tasks to display the first-letter icon (#15729)
Closes https://github.com/twentyhq/twenty/issues/15630

## Description
I've updated the Notes & Tasks to display the first-letter icon.

I only applied this change to the SummaryCard component to avoid
conflict with the content of
https://github.com/twentyhq/twenty/issues/6486.

## Test
<img width="1155" height="178" alt="スクリーンショット 2025-11-09 19 02 41"
src="https://github.com/user-attachments/assets/3b065f94-7bb8-4ba9-a0f0-3c32fb556e7e"
/>
<img width="1158" height="229" alt="スクリーンショット 2025-11-09 19 02 23"
src="https://github.com/user-attachments/assets/884ff3b6-2c48-4557-8b45-64f94a8fd6a1"
/>

Co-authored-by: Takuya Kurimoto <takuya004869@gmail.com>
2025-11-12 10:38:22 +01:00
Lucas BordeauandGitHub 5f3253d5a5 Fix issues with one to many activity targets (#15656)
This PR fixes issues with one to many activity target bugs described
here :
https://github.com/twentyhq/twenty/issues/14280#issuecomment-3490170714

It also improves the request that fetches notes and tasks in index
pages, to only fetch the notes and tasks identifier fields, thus
reducing the amount of network load.

Fixes https://github.com/twentyhq/twenty/issues/14280
2025-11-11 17:19:20 +01:00
de978960d0 [FIx] shouldBypassPermissionChecks for workspaceMember repository (#15706)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Pass `shouldBypassPermissionChecks: true` to
`getRepositoryForWorkspace('workspaceMember')` in
`1-11-clean-orphaned-user-workspaces.command.ts` to ensure member lookup
during orphan cleanup ignores permissions.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
543fd9fc01. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-11-11 17:17:42 +01:00
Lucas BordeauandGitHub 703d9cb08d Improved Kanban performance (#15714)
This PR improves Kanban performance to attain the stock library speed.

There are still some performance issues at load time and drop, but they
are harder to address.

Before, everything is re-rendering at every card move, full re-render at
drop :



https://github.com/user-attachments/assets/7a1cf419-c8d8-4d56-a1a3-4269dce7b5a9


After, only the columns and card outer containers get re-rendered for
d&d, only two columns re-render at drop :



https://github.com/user-attachments/assets/d2dea914-5cc3-4693-9c2d-c7c789ae3452



We can still improve performance and re-render but that would represent
a global effort on D&D on general, table has the same problem currently,
but since we implemented virtualization it is bearable for now.
2025-11-11 17:07:40 +01:00
Thomas des FrancsandGitHub e5b88f2bb2 Update changelog process to require user approval (#15760)
Adds a mandatory user approval step before committing and creating PRs
in the changelog creation process.

This ensures the AI always shows the full changelog content and waits
for user approval before proceeding.
2025-11-11 16:50:04 +01:00
561297436e Anchored tooltip (#15568)
Issue - 
- tooltip gets too long when groupby has too much data points
- we need max height on tooltips
- we need to be able to scroll inside the tooltip
- not possible if the tooltip is following the cursor (which library
enforces)
- its not easy to customize Nivo's own tooltip to make it work how we
want it

what we want - 
- let the tooltip anchor to the bar in such a way -- that the top of the
bar aligns with the vertical middle of the tooltip
- add max height to the tooltip

what I did - 
- use floating portal from floating-ui/react
- get the hover datum (ie hovered bars) dimensions on mouse enter to
render the tooltip
- anchor the tooltip at the calculated position
- floating-ui handles the basic things like flipping/offset/shift
- clear the states as required

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-11 16:47:41 +01:00
Thomas des FrancsandGitHub 652c8673e0 Release 1.10.0 (#15759)
## Release 1.10.0

This release includes:

- Calendar View for Objects - visualize records in a monthly calendar
view
- Dashboards in Labs (Beta) - create custom charts and visualizations
with workspace data

Changelog file:
`packages/twenty-website/src/content/releases/1.10.0.mdx`
Release date: 2025-11-11
2025-11-11 16:43:55 +01:00
Abdul RahmanandGitHub 2e359f5585 Fix AI table scroll overflow and tool input display (#15753)
- Fixed horizontal scroll overflow when tables appear in AI responses
- Fixed tool call input display to show only user-relevant input instead
of internal metadata (loadingMessage)

### Before

https://github.com/user-attachments/assets/870bf52d-7ffd-464e-9240-bd482ab19077


### After


https://github.com/user-attachments/assets/40a19fc0-6989-437f-b712-8141368179dc
2025-11-11 11:08:26 +01:00
Félix MalfaitandGitHub 11e07f90d2 refactor: Simplify CRUD services to leverage Common API (#15742)
## Summary

This PR refactors all Record CRUD services to use the Common API
(CommonQueryRunners) instead of directly accessing TwentyORM, achieving
**77% code reduction** while maintaining full functionality.

## Changes

### Code Reduction: -547 net lines (77%)
- **Before**: 901 lines across 5 services
- **After**: 354 lines (services + utility)
- **Deleted**: 547 lines of redundant code

### Services Simplified

| Service | Before | After | Reduction |
|---------|--------|-------|-----------|
| CreateRecordService | 142 | 59 | -83 lines |
| UpdateRecordService | 177 | 51 | -126 lines |
| DeleteRecordService | 137 | 51 | -86 lines |
| FindRecordsService | 233 | 68 | -165 lines |
| UpsertRecordService | 212 | 129 | -83 lines |

### Architecture Change

**Before:**
```
CRUD Services → TwentyORM
- Manual query building
- Manual permission checking
- Manual transformations
- Duplicated logic
```

**After:**
```
CRUD Services → CommonQueryRunners → TwentyORM
- Common API handles queries
- Common API handles permissions
- Common API handles transformations
- Single source of truth
```

### Module Dependencies Simplified

**Removed:**
- TwentyORMModule
- RecordPositionModule
- RecordTransformerModule
- WorkflowCommonModule

**Added:**
- CoreCommonApiModule
- WorkspaceMetadataCacheModule

**From 4 heavy dependencies → 2 clean dependencies**

## What Changed

### New Code
- `common-api-context-builder.util.ts` - Single shared utility (68
lines)

### Refactored Services
All services now follow a simple pattern:
1. Build Common API context
2. Call appropriate CommonQueryRunner
3. Return formatted result

Each service is now 50-120 lines instead of 140-230 lines.

### Type Fixes
- Fixed `FindRecordsParams.orderBy` type (was
`Partial<ObjectRecordOrderBy>`, now `ObjectRecordOrderBy`)
- Fixed `FindRecordsInput.gqlOperationOrderBy` type (same fix)

## Benefits

###  Code Quality
- 77% less code to maintain
- No code duplication
- Simpler, clearer logic
- Proper TypeScript types (no hacks)

###  Common API Integration
All services now get Common API benefits:
- Consistent permission checking
- Query hooks (before/after execution)
- Automatic input transformation
- Automatic position handling
- Result processing and enrichment
- Same behavior as REST/GraphQL

###  Safety Preserved
- createdBy actor metadata preserved for workflows
- All field validation maintained
- All transformations maintained
- All error handling maintained

###  No Breaking Changes
- Same external API for all services
- Workflows continue to work
- AI operations continue to work
- MCP operations continue to work

## Testing

-  TypeScript compiles
-  All files pass linting
-  No type casting hacks
-  Proper type safety throughout
- ⚠️ Integration tests recommended

## What Common API Handles For Us

1. **Record Position** - Automatic via `RecordPositionService`
2. **Input Transformation** - Automatic for NUMBER, RICH_TEXT, PHONES,
EMAILS, LINKS
3. **createdBy Actor** - Injected via `CreatedByCreateOnePreQueryHook` +
explicit workflow actor
4. **Field Validation** - Only processes valid fields
5. **Permissions** - Validates permissions before execution
6. **Query Hooks** - Before/after execution hooks work
7. **Error Handling** - Consistent exception handling

## Files Modified (12)

**Services (6):**
- create-record.service.ts
- update-record.service.ts
- delete-record.service.ts
- find-records.service.ts
- upsert-record.service.ts
- record-crud.module.ts

**Types (2):**
- find-records-params.type.ts
- record-crud-input.type.ts

**Workflows (1):**
- find-records.workflow-action.ts

**New Files (3):**
- common-api-context-builder.util.ts
- REFACTORING_COMPLETE.md
- REFACTORING_ANALYSIS.md

## Verification Checklist

- [x] TypeScript compiles
- [x] Linter passes
- [x] No type hacks (`as unknown as` removed)
- [x] createdBy preserved for workflows
- [x] Module dependencies simplified
- [x] Common API integration complete
- [ ] Integration tests pass (recommended)
- [ ] Workflow execution tested (recommended)

## Related Issues

This refactoring establishes the pattern for making CRUD operations
consistent across all presentation layers (REST, GraphQL,
Tools/Workflows/AI/MCP).
2025-11-11 11:07:36 +01:00
martmullandGitHub 9880f192a5 Move composite types to twenty-shared (#15741) 2025-11-10 22:11:52 +01:00
Charles BochetandGitHub 7099b1c174 Fix export CSV not using right columns (#15752)
Fixes https://github.com/twentyhq/twenty/issues/15575
2025-11-10 22:00:39 +01:00
Abdul RahmanandGitHub 194a579a03 fix: Replace angle bracket placeholders with curly braces in docs to fix crowdin's tags mismatch errors (#15751) 2025-11-11 02:20:48 +05:30
Shantanu GuptaandGitHub 06b8ea7c36 FIX: export view not exporting all records (#15509)
Fixes #15508 
Addresses the issue where the "Export View" functionality was not
exporting all records from a view. Users reported that only a subset of
records were exported, even when the view contained more. This led to
incomplete data exports.

The core of the problem was found within the `useLazyFetchAllRecords`
hook. The `fetchMoreRecordsLazy` function, which is responsible for
fetching subsequent pages of data during the export process, was
inadvertently using a default page limit (`DEFAULT_SEARCH_REQUEST_LIMIT`
of 60 records) instead of the intended `pageSize` (200 records). This
discrepancy caused the export process to prematurely stop fetching
records.

The PR modifies
`packages/twenty-front/src/modules/object-record/hooks/useLazyFetchAllRecords.ts`
to explicitly pass the `limit` parameter (which correctly reflects the
`pageSize`) to the `fetchMoreRecordsLazy` function. This ensures that
all subsequent data fetches during an export operation adhere to the
configured page size, allowing for the complete retrieval of all
records.
2025-11-10 21:25:39 +01:00
neo773andGitHub 39017f43b8 handle invalid/expired syncCursor (#15715) 2025-11-10 18:18:17 +01:00
WeikoandGitHub 22a81f705b Add global datasource to seeded feature flags (#15748) 2025-11-10 17:05:25 +00:00
WeikoandGitHub 02fda92a93 Global workspace datasource poc (#15744)
## Context
This PR introduces a Global Workspace DataSource that consolidates
workspace-specific database access through a single TypeORM DataSource
instance with AsyncLocalStorage-based context management instead of N
workspace datasources.

- Created GlobalWorkspaceDataSource extending TypeORM's DataSource to
manage multiple workspaces with entity metadata caching (1-hour TTL)
- Implemented AsyncLocalStorage for workspace context propagation
(WorkspaceContextForStorage) containing workspace ID, metadata,
permissions, and feature flags
- Modified query execution flow to wrap operations in workspace context
via GlobalWorkspaceOrmManager.executeInWorkspaceContext()
- Added schema name to entity schemas for proper multi-tenant database
separation

Next: 
- use the new global workspace datasource everywhere and deprecate
workspace datasource factory
- improve metadata caching using a short TTL to avoid multiple calls to
redis
- Leverage the new WorkspaceContextALS and put it higher in the request
hierarchy to have access to permission, metadata and featureflag
everywhere --- build it manually for commands --- find a way to
propagate it in jobs?
- Remove PG_POOL patch once we have a unique datasource and increase
global datasource pool size

## Implementation
Why ALS:

1. Automatic Per-Request Isolation

With schema-based multi-tenancy, each workspace has its own PostgreSQL
schema
(e.g. workspace_20202020-1c25-4d02-bf25-6aeccf7ea419).
The critical challenge is ensuring that concurrent requests from
different tenants don't interfere with each other.
```typescript
// Request A (Workspace 1) and Request B (Workspace 2) executing concurrently

// Without ALS: Race condition — they'd share the same global state!
// With ALS: Each request has isolated context ✓
```
ALS automatically isolates context per async execution chain, so:
- Request from Tenant A → ALS stores workspaceId: "tenant-a" → Queries
hit workspace_tenant_a schema
- Request from Tenant B → ALS stores workspaceId: "tenant-b" → Queries
hit workspace_tenant_b schema

 No interference, even when executing simultaneously on the same
Node.js event loop.

2. No Manual Context Passing

Before ALS, you'd need to pass workspaceId through every function call:
```typescript
//  Without ALS - Context threading nightmare
getRepository(workspaceId, entity)
  → createEntityManager(workspaceId)
    → getMetadata(workspaceId, target)
      → findInCache(workspaceId, cacheKey)
```
With ALS:
```typescript
//  With ALS - Clean, implicit context
getRepository(entity)          // Reads workspaceId from ALS
  → createEntityManager()      // Reads workspaceId from ALS
    → getMetadata(target)      // Reads workspaceId from ALS
      → findInCache(cacheKey)  // Reads workspaceId from ALS
```
example
```typescript
override findMetadata(target: EntityTarget<ObjectLiteral>): EntityMetadata | undefined {
  const context = getWorkspaceContext(); // 👈 Automatically gets the right workspace!
  const { workspaceId, metadataVersion } = context;
  const cacheKey = `${workspaceId}-${metadataVersion}`;
  // ... returns metadata for THIS workspace's schema
}
```

3. Async Chain Propagation

Node.js operations are heavily async. ALS automatically propagates
context through:

- async/await chains
- Promise chains
- Callbacks

```typescript
executeInWorkspaceContext(workspaceId, async () => {
  await prepareContext();           // Has context ✓
  const results = await run();      // Has context ✓
  await enrichResults();            // Has context ✓

  // Even nested async operations maintain context!
  await Promise.all([
    saveToCache(),   // Has context ✓
    emitEvent(),     // Has context ✓
    logMetrics(),    // Has context ✓
  ]);
});
```
5. Schema-Specific Metadata Caching

The implementation caches entity metadata per workspace + version:
```typescript
// Cache key format: "workspaceId-metadataVersion"
const cacheKey = `${workspaceId}-${metadataVersion}`;
```
Why this matters with schemas:

- Each workspace has different table structures (custom fields, objects)
- EntitySchema includes schema: "workspace_xxx" property
- Each cached metadata points to the correct schema

ALS ensures getWorkspaceContext() returns the right workspaceId,
so you always get the correct schema's metadata from cache.

6. Single DataSource for All Tenants

The key change here:
```typescript
//  Old approach: One DataSource per tenant
const dataSourceTenantA = new DataSource({ schema: 'workspace_a' });
const dataSourceTenantB = new DataSource({ schema: 'workspace_b' });
// Problem: Hundreds of DB connection pools!
```
```typescript
//  New approach: One shared DataSource + ALS context
const globalDataSource = new GlobalWorkspaceDataSource();

// ALS determines which schema to use at runtime
```
When you call:
```typescript
globalDataSource.getRepository('person');
```
It internally does:
```typescript
const context = getWorkspaceContext();  // Gets current tenant from ALS
const metadata = this.findMetadata('person'); // Finds metadata for THIS tenant's schema
// EntityMetadata includes: schema: "workspace_20202020-1c25..."
// TypeORM automatically queries: SELECT * FROM "workspace_20202020-1c25...".person
```
7. Request Lifecycle Example

```typescript
// 1. GraphQL request arrives: "query people { ... }"
// 2. Middleware extracts authContext.workspace.id = "tenant-a"
// 3. Query runner wraps execution in ALS:
executeInWorkspaceContext("tenant-a", async () => {
  // 4. Everything inside has access to workspace context:
  const repo = getRepository('person');      // ALS → tenant-a
  const metadata = getMetadata('person');    // ALS → tenant-a → cache["tenant-a-v5"]

  // 5. TypeORM builds query with correct schema:
  // SELECT * FROM "workspace_tenant_a"."person" WHERE ...

  // 6. Even nested calls work:
  await saveAuditLog();  // ALS → tenant-a → correct audit schema
  await emitWebhook();   // ALS → tenant-a → correct tenant webhook
});
// 7. Request completes, ALS context automatically cleaned up
```

8. Safety & Error Prevention

```typescript
// If you forget to set context:
const context = getWorkspaceContext();
//  Throws: "Workspace context not set..."
// Fails fast rather than querying wrong schema!

// Can't accidentally query wrong tenant:
// Context is immutable within execution scope
```
2025-11-10 17:32:49 +01:00
Paul RastoinandGitHub 7a1e699fc8 Twenty standard and workspace custom applications 1/3 (#15625)
# Introduction
related to https://github.com/twentyhq/core-team-issues/issues/1833
In this PR we're starting the sync-metadata and standardIds deprecation
by introducing `twenty-standard` application that will regroup every
standard object such as company and opportunities. But also the
`custom-workspace-application` which is an app created at the same time
as a workspace and that will regroup everything configure within the
workspace ( custom objects fields etc )

## What's done
On both new workspace and seeded workspace creation:
- Creating a custom workspace app
- Creating a twenty standard app
- Refactored the seed core schema and workspace creation to be run
within a transaction in order to handle circular dependency foreignkey
requirements ( which is deferred for app toward workspace )
- Updated workspace entity to have a custom workspace relation (
nullable for the moment until we implem an upgrade command to handle
retro comp )
- Integration testing on user, workspace creation deletion and expected
default apps creation
- ~~Soft deleted user on `deleteUser`~~ Done by marie and rebased on it

## What's next
- Update seeder to propagate the `twenty-standard` workspace
`applicationId` to every standard synchronized entities ( cheap and fast
iteration through the about to be deprecated sync-metadata as an easy
way to synchronize standards metadata entities ).
- Update seeder to propagate the `custom-workspace-application`
workspace `applicationId` to anything custom ( `pets` and `rockets` )
- Prepend `custom-workspace-application` `applicationId` to every
metadata API operations ( create a specific cache etc )
- Upgrade command on all existing workspace to create a custom app and
associate its applicationId to any existing custom entities
- Make `universalIdentifier` and `applicationId` required for any
syncable entity
2025-11-10 16:13:12 +01:00
Félix MalfaitandGitHub 9a80164cf3 Add comprehensive permission guard coverage across GraphQL and REST endpoints (#15739)
This PR enhances our security model by ensuring all GraphQL resolvers
and REST API endpoints have appropriate permission guards.

## Changes

### ESLint Rules
- Enhanced `graphql-resolvers-should-be-guarded` to require permission
guards on all resolvers (Query, Mutation, Subscription), not just
mutations
- Enhanced `rest-api-methods-should-be-guarded` to require permission
guards on all REST endpoints (GET, POST, PUT, PATCH, DELETE), not just
mutating methods
- Both rules now enforce consistent security: authentication guards +
permission guards for all endpoints

### Permission Guards Added

**Public Endpoints** - Added `NoPermissionGuard`:
- Auth-related queries (checkUserExists, findWorkspaceFromInviteHash,
validatePasswordResetToken)
- Billing webhooks (Stripe callbacks)
- SSO callbacks (SAML authentication)
- Workflow webhooks
- Cloudflare webhooks
- Route trigger endpoints
- GraphQL subscriptions
- Current workspace queries
- Geo-map address autocomplete
- View-related read operations (view-field, view-filter, view-group,
view-sort, view-filter-group)

**Settings Permission Guards** - Added `SettingsPermissionGuard`:
- API Keys management: `PermissionFlagType.API_KEYS_AND_WEBHOOKS`
- Webhooks management: `PermissionFlagType.API_KEYS_AND_WEBHOOKS`
- Page Layouts (write operations): `PermissionFlagType.LAYOUTS`
- REST Metadata API: `PermissionFlagType.DATA_MODEL`
- Agent operations: `PermissionFlagType.AI`
- Remote servers: `PermissionFlagType.DATA_MODEL`
- Remote tables: `PermissionFlagType.DATA_MODEL`
- Serverless functions: `PermissionFlagType.WORKFLOWS`

**Custom Permission Guards** - Added `CustomPermissionGuard`:
- REST Core API (permissions checked at query execution layer)
- Timeline calendar events (permission checks in service layer)
- Timeline messaging (permission checks in service layer)
- Search operations (permission checks in service layer)
- View operations (permission checks via dedicated view permission
guards)

### View Permission Guards
- Created dedicated `FindManyViewsPermissionGuard` and
`FindOneViewPermissionGuard` for reading views
- Created `CreateViewPermissionGuard` for view creation with
visibility-based permission checks
- All view child entities (view-field, view-filter, view-sort,
view-group, view-filter-group) use `NoPermissionGuard` for reads
- Write operations on view child entities use dedicated permission
guards that check parent view access

### Page Layout Permissions
- Read operations (GET/Query) now use `NoPermissionGuard` - users can
view layouts without LAYOUTS permission
- Write operations (POST/PATCH/DELETE/Mutation) require
`SettingsPermissionGuard(PermissionFlagType.LAYOUTS)`
- Applied consistently across page-layout, page-layout-tab, and
page-layout-widget endpoints

## Security Model
All endpoints now follow a consistent pattern:
1. **Authentication**: `UserAuthGuard`, `WorkspaceAuthGuard`, or
`PublicEndpointGuard`
2. **Authorization**: One of:
- `SettingsPermissionGuard(PermissionFlagType.XXX)` - for settings/admin
operations
- `CustomPermissionGuard` - when permissions are checked in service/data
layer
   - `NoPermissionGuard` - for public or non-sensitive read operations

The ESLint rules automatically enforce this pattern going forward.

## Stats
- 47 files changed
- 603 insertions, 163 deletions
- 3 new guard files created
2025-11-10 12:17:38 +01:00
BOHEUSandGitHub ae2d399d6e Hacktober apps fix (#15733)
- update dependencies in mailchimp, stripe and last email interaction
apps
- fix logic in mailchimp integration, now it's triggered by update of
People records and allows for update Mailchimp records
- fix logic in stripe integration, now properly reads data from webhook
- update READMEs to make it more understandable to non-technical users
2025-11-10 09:37:09 +01:00
912c668eb5 i18n - docs translations (#15735)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-09 23:20:15 +01:00
2c0df3ca99 i18n - translations (#15734)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-09 21:32:52 +01:00
9f594cda1c Slash Command Implementation in Advanced Text Editor (#15488)
Part of Fixing Issue #14976 

### Pull Request Summary: SlashCommand Integration in Advanced Text
Editor

This pull request introduces **SlashCommand functionality** within the
Advanced Text Editor, specifically used in the **Workflow node** of
**Send Email body** components. The implementation leverages the
`@tiptap/suggestion` extension from the TipTap ecosystem, enabling
dynamic styling and command execution via a custom dropdown triggered by
typing `/`.

---

### Implementation Overview

#### 1. **Custom Extension & Dropdown Rendering**
- A new extension was created to handle SlashCommand interactions.
- This extension renders a **Dropdown component** that displays
available commands with relevant styles, icons etc.

#### 2. **Command Configuration**
- Each command includes:
  - Visibility and active state logic
  - Execution behavior upon selection
- All commands are initialized and configured centrally.

#### 3. **Search & Filtering**
- As users type after the `/`, the command list is **filtered based on
the query**.
- For example, typing `/car` filters and displays matching commands in
the dropdown.

#### 4. **Dropdown Lifecycle & Positioning**
- The dropdown is rendered using React lifecycle hooks provided by
`SuggestionTip`:
- `onStart`: Initializes state, sets selected command, and captures
cursor position via `DOMRect`.
- `onUpdate`, `onKeyDown`, `onExit`: Manage dropdown updates and
interactions.
- Positioning is handled via a **`useFloating` hook**, which aligns the
dropdown relative to the cursor and editor bounds.
- The dropdown is rendered in a **react-portal**, wrapped in the current
theme for consistent styling and animation.


#### 6. **State Management**
- A dedicated `SlashCommandState.ts` file manages:
  - Callback functions
  - Current command and selected item
  - Cleanup utilities for event listeners
  - Dropdown navigation (arrow keys, enter key)

#### 7. **Integration Points**
- SlashCommand functionality is now **enabled in Send Email body of the
Workflow**.
- Relevant changes have been applied to support this components in
Storybook as well.

[slash command
test.webm](https://github.com/user-attachments/assets/5c537844-8987-4ce5-9fca-b29ea93d8063)


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Updates Portuguese (Brazil and Portugal) generated locale files,
including a new editor hint string for “Enter text or type '/' for
commands,” plus assorted translation tweaks.
> 
> - **i18n/locales**:
> - **Portuguese (Brazil) `src/locales/generated/pt-BR.ts`**: Add new
editor hint message (`"Enter text or Type '/' for commands"`) and adjust
multiple translations/wording.
> - **Portuguese (Portugal) `src/locales/generated/pt-PT.ts`**: Add the
same editor hint message and refine numerous translations/labels.
> - No functional code changes; translation files regenerated/updated.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b3d7407525. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-11-09 21:18:56 +01:00
1aa9df1d2d i18n - docs translations (#15731)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-09 15:19:56 +01:00
Abdul RahmanandGitHub 4182209ee1 Docs/organize locales under l (#15730) 2025-11-09 14:02:21 +01:00
Abdul RahmanandGitHub 4a15cbc97c Add token renewal to agent chat transport (#15727) 2025-11-09 13:57:24 +01:00
a21680d6a3 refactor: Move translated docs to /l/{locale}/ directory structure (#15726)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-11-09 12:22:38 +00:00
Abdul RahmanandGitHub 7993e14d0a docs: Fix French navigation labels and translated internal links (#15723)
## Summary
Fixes French documentation navigation labels and internal link redirects
to English pages.

## Changes
1. **Translated French navigation** - All tab/group labels in
`docs.json` now display in French
2. **Automated link fixing** - Created `fix-translated-links.sh` script
that adds `/fr/` prefix to internal links
3. **CI Integration** - Script runs automatically after Crowdin syncs
translations
2025-11-09 13:16:37 +01:00
a4ac66cb4e i18n - docs translations (#15725)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-08 23:20:14 +01:00
1bd1165d2e i18n - docs translations (#15724)
Created by Github action

---------

Co-authored-by: Abdul Rahman <ar5438376@gmail.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-08 21:20:40 +01:00
Abdul RahmanandGitHub 06d8c8c76a Fix find tool filters by mapping many-to-one relations to fieldId (#15716)
**Root Cause**  
Many-to-one relation filters were being exposed under the relation name
(e.g., `company`) instead of the corresponding foreign-key attribute
(e.g., `companyId`).

**Change**  
- Detect many-to-one relation metadata and remap those filter keys to
`<fieldName>Id`.
- Removed some unused code unrelated to this fix.
2025-11-08 14:32:06 +01:00
4c4eeef5ae i18n - docs translations (#15721)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-08 13:22:29 +01:00
f740bac988 add documentation i18n workflows for Crowdin (#15538)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-11-08 11:24:07 +01:00
154fb4665e i18n - docs translations (#15720)
Created by Github action

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds a full French documentation set covering developers (API,
webhooks, backend/frontend, self‑hosting) and user guide (CRM
essentials, data model, workflows, settings, integrations, pricing,
reporting).
> 
> - **Docs (FR i18n)**:
> - **Developers**: Add `API`, `Webhooks`, backend (best practices,
custom objects, feature flags, architecture, commands, Zapier), frontend
(best practices, architecture, commands, hotkeys, style guide,
Storybook, Figma), self‑hosting (Docker Compose, upgrade guide, cloud
providers), introduction.
> - **User Guide**: Add getting started (what is Twenty,
create/configure workspace, migration, import/export), CRM essentials
(contacts/accounts, pipelines, views), data model (objects, fields,
relations, table views), collaboration (emails/calendars, notes, tasks),
integrations API (overview, integrations), workflows (getting started,
features, credits, internal automations, services), settings (profile,
permissions, members, domains, releases, email/calendar setup), pricing
(billing/FAQ), reporting overview, resources (GitHub, glossary),
introduction.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9ba8c24571. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-11-08 10:20:29 +01:00
0fc538ac09 i18n - docs translations (#15719)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-08 10:01:06 +01:00
136289562e i18n - translations (#15718)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-08 07:48:39 +01:00
caecf2d0c2 i18n - translations (#15717)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-08 07:43:59 +01:00
0ca0cce9a2 i18n - translations (#15713)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-07 18:33:14 +01:00
Félix MalfaitandGitHub b7f5445926 fix: rename SettingsPermissionsGuard to SettingsPermissionGuard for consistency (#15712)
## Problem

The ESLint rule `graphql-resolvers-should-be-guarded` introduced in
#15392 was failing on main because the guard `SettingsPermissionsGuard`
had inconsistent naming.

## Root Cause

The guard was named `SettingsPermissionsGuard` (with an 's') which was
inconsistent with other permission guards:
-  `CustomPermissionGuard`  
-  `NoPermissionGuard`
-  `ImpersonatePermissionGuard`
-  `SettingsPermissionsGuard` (inconsistent!)

The ESLint rule checks if guard names end with `PermissionGuard`, but
`SettingsPermissionsGuard` ends with `sGuard`, so it wasn't recognized
as a permission guard.

## Solution

Renamed the guard to be consistent with the naming convention:

1.  Renamed file: `settings-permissions.guard.ts` →
`settings-permission.guard.ts`
2.  Renamed export: `SettingsPermissionsGuard` →
`SettingsPermissionGuard`
3.  Renamed internal class: `SettingsPermissionsMixin` →
`SettingsPermissionMixin`
4.  Updated all 122 references across 44 files in the codebase
5.  Renamed test file: `settings-permissions.guard.spec.ts` →
`settings-permission.guard.spec.ts`

## Testing

-  `npx nx run twenty-server:lint` passes
-  `npx nx run twenty-server:typecheck` passes
-  No references to the old name remain in the codebase
-  All previously failing resolver files now pass ESLint validation

## Related

Fixes issues introduced in #15392
2025-11-07 18:22:28 +01:00
martmullandGitHub bce1bcf1fa Fix workflow run updates real time (#15701)
as title

## after


https://github.com/user-attachments/assets/34239b6e-16d6-4afd-9a54-cb4767179bea
2025-11-07 15:54:13 +01:00
neo773andGitHub f91c2bb729 fix exceptionHandlerService.captureExceptions in MessageImportExceptionHandlerService (#15703) 2025-11-07 15:53:26 +01:00
65014cbf8d i18n - translations (#15705)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-07 15:47:00 +01:00
Félix MalfaitandGitHub cff17db6cb Enhance role-check system with stricter checks (#15392)
## Overview

This PR strengthens our permission system by introducing more granular
role-based access control across the platform.

## Changes

### New Permissions Added
- **Applications** - Control who can install and manage applications
- **Layouts** - Control who can customize page layouts and UI structure
- **AI** - Control access to AI features and agents
- **Upload File** - Separate permission for file uploads
- **Download File** - Separate permission for file downloads (frontend
visibility)

### Security Enhancements
- Implemented whitelist-based validation for workspace field updates
- Added explicit permission guards to core entity resolvers
- Enhanced ESLint rule to enforce permission checks on all mutations
- Created `CustomPermissionGuard` and `NoPermissionGuard` for better
code documentation

### Affected Components
- Core entity resolvers: webhooks, files, domains, applications,
layouts, postgres credentials
- Workspace update mutations now use whitelist validation
- Settings UI updated with new permission controls

### Developer Experience
- ESLint now catches missing permission guards during development
- Explicit guard markers make permission requirements clear in code
review
- Comprehensive test coverage for new permission logic

## Testing
-  All TypeScript type checks pass
-  ESLint validation passes
-  New permission guards properly enforced
-  Frontend UI displays new permissions correctly

## Migration Notes
Existing workspaces will need to assign the new permissions to roles as
needed. By default, all new permissions are set to `false` for non-admin
roles.
2025-11-07 15:37:17 +01:00
Raphaël BosiandGitHub 44d6ec2594 Widget: Allow resizing from all corners and sides (#15680)
https://github.com/user-attachments/assets/3e4e1da2-87e6-440e-8371-835ef6eccf59
2025-11-07 15:28:39 +01:00
GuillimandGitHub 2274a937bd first step (#15687)
TODO : 

-> for test integreation for this connect 
-> add validation in common API

Fixes https://github.com/twentyhq/core-team-issues/issues/1278
2025-11-07 13:49:57 +00:00
Paul RastoinandGitHub f50d9bfa43 Activate IS_WORKSPACE_MIGRATION_V2_ENABLED for new workspaces (#15700) 2025-11-07 13:41:25 +00:00
MarieandGitHub 0992d8031b [Fix] fix command dry run (#15697) 2025-11-07 13:32:23 +01:00
Abdul RahmanandGitHub 54815196c1 Improve AI Tool Step Renderer Layout and JSON Tree Scrolling (#15698)
### Before


https://github.com/user-attachments/assets/a222a6ff-550c-453b-bc0b-ee9bdb925956


### After



https://github.com/user-attachments/assets/249b7097-8dc1-4611-8205-2a43cb015a33
2025-11-07 13:31:05 +01:00
martmullandGitHub 196a75ec0c Fix typing error (#15699)
Fix typing error
2025-11-07 13:29:16 +01:00
martmullandGitHub aa48a68a34 Increase packages versions (#15694)
As title
2025-11-07 10:46:43 +01:00
MarieandGitHub 66ef867cf5 Do not revert isSystem update for workspaceMember (#15691)
Until this is done: [Make workspaceMembers
non-system](https://github.com/twentyhq/twenty/issues/15688)

Let's make that update to allow us to have workspaces with
workspaceMember not being system object, to allow user to customize
their data model.
2025-11-07 10:04:10 +01:00
c9d7361e7c i18n - translations (#15689)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-06 19:40:28 +01:00
MarieandGitHub 4ce93aee52 Fix user deletion flows (#15614)
**Before**
- any user with workpace_members permission was able to remove a user
from their workspace. This triggered the deletion of workspaceMember +
of userWorkspace, but did not delete the user (even if they had no
workspace left) nor the roleTarget (acts as junction between role and
userWorkspace) which was left with a userWorkspaceId pointing to
nothing. This is because roleTarget points to userWorkspaceId but the
foreign key constraint was not implemented
- any user could delete their own account. This triggered the deletion
of all their workspaceMembers, but not of their userWorkspace nor their
user nor the roleTarget --> we have orphaned userWorkspace, not
technically but product wise - a userWorkspace without a workspaceMember
does not make sense

So the problems are
- we have some roleTargets pointing to non-existing userWorkspaceId
(which caused https://github.com/twentyhq/twenty/issues/14608 )
- we have userWorkspaces that should not exist and that have no
workspaceMember counterpart
- it is not possible for a user to leave a workspace by themselves, they
can only leave all workspaces at once, except if they are being removed
from the workspace by another user

**Now**
- if a user has multiple workspaces, they are given the possibility to
leave one workspace while remaining in the others (we show two buttons:
Leave workspace and Delete account buttons). if a user has just one
workspace, they only see Delete account
- when a user leaves a workspace, we delete their workspaceMember,
userWorkspace and roleTarget. If they don't belong to any other
workspace we also soft-delete their user
- soft-deleted users get hard deleted after 30 days thanks to a cron
- we have two commands to clean the orphans roleTarget and userWorkspace
(TODO: query db to see how many must be run)

**Next**
- once the commands have been run, we can implement and introduce the
foreign key constraint on roleTarget


Fixes https://github.com/twentyhq/twenty/issues/14608
2025-11-06 18:29:12 +00:00
bfe1f47065 Create old fields design widget (#15645)
In this PR:

- Pass `layoutMode` and `tabId` via PageLayoutContentContext provider
- Getting `pageLayoutType` from the current page layout
- Getting isInPinnedTab through `useIsInPinnedTab` hook

## Before

<img width="3456" height="2160" alt="CleanShot 2025-11-06 at 14 22
44@2x"
src="https://github.com/user-attachments/assets/763bb413-5739-45ef-85ed-82a72415886f"
/>

## After

<img width="3456" height="2162" alt="CleanShot 2025-11-06 at 14 20
38@2x"
src="https://github.com/user-attachments/assets/eee6cccd-9d36-426e-a22f-400e8f7f9413"
/>

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-06 18:16:42 +01:00
Thomas TrompetteandGitHub 33c08ad437 Edit workflow and serverless throttling (#15648)
Serverless:  1000 / min.

Workflows: 100 / min. This is a security in case of infinite loops.
2025-11-06 17:47:27 +01:00
Raphaël BosiandGitHub 931d12c77b Add animations on widget buttons and on action buttons (#15631)
Animated:
- Grip
- Trash can
- Action buttons


https://github.com/user-attachments/assets/1cac7a5e-2036-4308-9622-3b4809ae90a3
2025-11-06 17:38:05 +01:00
Paul RastoinandGitHub 137aba049d Fix tsconfigpaths root (#15683)
# Introduction
We've facing facing intra package build error for a moment such as:
```ts
vite v7.1.12 building for production...
src/components/BaseEmail.tsx:20:19 - error TS2719: Type 'import("/Users/paulrastoin/ws/twenty/node_modules/@lingui/core/dist/index").I18n' is not assignable to type 'import("/Users/paulrastoin/ws/twenty/node_modules/@lingui/core/dist/index").I18n'. Two different types with this name exist, but they are unrelated.
  Types have separate declarations of a private property '_locale'.

20     <I18nProvider i18n={i18nInstance}>
                     ~~~~

  node_modules/@lingui/react/dist/shared/react.b2b749a9.d.ts:42:5
    42     i18n: I18n;
           ~~~~
    The expected type comes from property 'i18n' which is declared here on type 'IntrinsicAttributes & Omit<I18nContext, "_"> & { children?: ReactNode; }'
```

and now since hacktoberfest merge getting even more such as:
```ts
➜  twenty git:(main) ✗ npx nx build twenty-emails

   ✔  2/2 dependent project tasks succeeded [2 read from cache]

   Hint: you can run the command with --verbose to see the full dependent project outputs

——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

[tsconfig-paths] An error occurred while parsing "/Users/paulrastoin/ws/twenty/packages/twenty-apps/hacktoberfest-2025/linkedin-browser-extension/browser-extension/tsconfig.json". See below for details. To disable this message, set the `ignoreConfigErrors` option to true.
TSConfckParseError: failed to resolve "extends":"./.wxt/tsconfig.json" in /Users/paulrastoin/ws/twenty/packages/twenty-apps/hacktoberfest-2025/linkedin-browser-extension/browser-extension/tsconfig.json
    at resolveExtends (file:///Users/paulrastoin/ws/twenty/node_modules/tsconfck/src/parse.js:261:8)
    at parseExtends (file:///Users/paulrastoin/ws/twenty/node_modules/tsconfck/src/parse.js:196:24)
    ... 5 lines matching cause stack trace ...
    at async createBuilder (file:///Users/paulrastoin/ws/twenty/node_modules/vite/dist/node/chunks/config.js:34104:19)
    at async CAC.<anonymous> (file:///Users/paulrastoin/ws/twenty/node_modules/vite/dist/node/cli.js:629:10) {
  code: 'EXTENDS_RESOLVE',
  cause: Error: Cannot find module './.wxt/tsconfig.json'
  Require stack:
  - /Users/paulrastoin/ws/twenty/packages/twenty-apps/hacktoberfest-2025/linkedin-browser-extension/browser-extension/tsconfig.json
      at Module._resolveFilename (node:internal/modules/cjs/loader:1410:15)
      at require.resolve (node:internal/modules/helpers:163:19)
      at resolveExtends (file:///Users/paulrastoin/ws/twenty/node_modules/tsconfck/src/parse.js:249:14)
      at parseExtends (file:///Users/paulrastoin/ws/twenty/node_modules/tsconfck/src/parse.js:196:24)
      at Module.parse (file:///Users/paulrastoin/ws/twenty/node_modules/tsconfck/src/parse.js:54:23)
      at async Promise.all (index 21)
      at async BasicMinimalPluginContext.configResolved (/Users/paulrastoin/ws/twenty/node_modules/vite-tsconfig-paths/dist/index.js:134:9)
      at async Promise.all (index 0)
      at async resolveConfig (file:///Users/paulrastoin/ws/twenty/node_modules/vite/dist/node/chunks/config.js:35892:2)
      at async createBuilder (file:///Users/paulrastoin/ws/twenty/node_modules/vite/dist/node/chunks/config.js:34104:19) {
    code: 'MODULE_NOT_FOUND',
    requireStack: [
      '/Users/paulrastoin/ws/twenty/packages/twenty-apps/hacktoberfest-2025/linkedin-browser-extension/browser-extension/tsconfig.json'
    ]
  },
  tsconfigFile: '/Users/paulrastoin/ws/twenty/packages/twenty-apps/hacktoberfest-2025/linkedin-browser-extension/browser-extension/tsconfig.json'
}
vite v7.1.12 building for production...
src/components/BaseEmail.tsx:20:19 - error TS2719: Type 'import("/Users/paulrastoin/ws/twenty/node_modules/@lingui/core/dist/index").I18n' is not assignable to type 'import("/Users/paulrastoin/ws/twenty/node_modules/@lingui/core/dist/index").I18n'. Two different types with this name exist, but they are unrelated.
  Types have separate declarations of a private property '_locale'.

20     <I18nProvider i18n={i18nInstance}>
                     ~~~~

  node_modules/@lingui/react/dist/shared/react.b2b749a9.d.ts:42:5
    42     i18n: I18n;
           ~~~~
    The expected type comes from property 'i18n' which is declared here on type 'IntrinsicAttributes & Omit<I18nContext, "_"> & { children?: ReactNode; }'

✓ 492 modules transformed.

[vite:dts] Start generate declaration files...
computing gzip size (31)...[vite:dts] Declaration files built in 981ms.

dist/locales/generated/zh-CN.mjs        4.16 kB │ gzip:   2.02 kB
dist/locales/generated/zh-TW.mjs        4.21 kB │ gzip:   2.05 kB
dist/locales/generated/en.mjs           4.34 kB │ gzip:   1.28 kB
dist/locales/generated/fi-FI.mjs        4.45 kB │ gzip:   1.90 kB
dist/locales/generated/af-ZA.mjs        4.50 kB │ gzip:   1.88 kB
dist/locales/generated/no-NO.mjs        4.52 kB │ gzip:   1.85 kB
dist/locales/generated/da-DK.mjs        4.52 kB │ gzip:   1.84 kB
dist/locales/generated/pt-BR.mjs        4.54 kB │ gzip:   1.89 kB
dist/locales/generated/sv-SE.mjs        4.54 kB │ gzip:   1.88 kB
dist/locales/generated/nl-NL.mjs        4.55 kB │ gzip:   1.87 kB
dist/locales/generated/pt-PT.mjs        4.56 kB │ gzip:   1.88 kB
dist/locales/generated/it-IT.mjs        4.59 kB │ gzip:   1.87 kB
dist/locales/generated/pl-PL.mjs        4.66 kB │ gzip:   2.04 kB
dist/locales/generated/cs-CZ.mjs        4.67 kB │ gzip:   2.05 kB
dist/locales/generated/es-ES.mjs        4.70 kB │ gzip:   1.90 kB
dist/locales/generated/tr-TR.mjs        4.70 kB │ gzip:   2.02 kB
dist/locales/generated/de-DE.mjs        4.71 kB │ gzip:   1.97 kB
dist/locales/generated/ca-ES.mjs        4.73 kB │ gzip:   1.92 kB
dist/locales/generated/ko-KR.mjs        4.73 kB │ gzip:   2.14 kB
dist/locales/generated/ro-RO.mjs        4.73 kB │ gzip:   1.95 kB
dist/locales/generated/fr-FR.mjs        4.74 kB │ gzip:   1.92 kB
dist/locales/generated/hu-HU.mjs        4.82 kB │ gzip:   2.09 kB
dist/locales/generated/he-IL.mjs        4.88 kB │ gzip:   1.99 kB
dist/locales/generated/ja-JP.mjs        4.95 kB │ gzip:   2.19 kB
dist/locales/generated/vi-VN.mjs        5.19 kB │ gzip:   2.14 kB
dist/locales/generated/ar-SA.mjs        5.35 kB │ gzip:   2.21 kB
dist/locales/generated/pseudo-en.mjs    5.68 kB │ gzip:   2.27 kB
dist/locales/generated/sr-Cyrl.mjs      5.82 kB │ gzip:   2.32 kB
dist/locales/generated/uk-UA.mjs        6.11 kB │ gzip:   2.41 kB
dist/locales/generated/el-GR.mjs        6.47 kB │ gzip:   2.53 kB
dist/locales/generated/ru-RU.mjs        6.62 kB │ gzip:   2.55 kB
dist/index.mjs                        822.22 kB │ gzip: 179.78 kB
dist/locales/generated/zh-CN.js        4.23 kB │ gzip:   2.08 kB
dist/locales/generated/zh-TW.js        4.28 kB │ gzip:   2.10 kB
dist/locales/generated/en.js           4.41 kB │ gzip:   1.33 kB
dist/locales/generated/fi-FI.js        4.52 kB │ gzip:   1.95 kB
dist/locales/generated/af-ZA.js        4.56 kB │ gzip:   1.93 kB
dist/locales/generated/no-NO.js        4.58 kB │ gzip:   1.90 kB
dist/locales/generated/da-DK.js        4.59 kB │ gzip:   1.89 kB
dist/locales/generated/pt-BR.js        4.60 kB │ gzip:   1.94 kB
dist/locales/generated/sv-SE.js        4.61 kB │ gzip:   1.93 kB
dist/locales/generated/nl-NL.js        4.62 kB │ gzip:   1.92 kB
dist/locales/generated/pt-PT.js        4.63 kB │ gzip:   1.93 kB
dist/locales/generated/it-IT.js        4.66 kB │ gzip:   1.92 kB
dist/locales/generated/pl-PL.js        4.73 kB │ gzip:   2.09 kB
dist/locales/generated/cs-CZ.js        4.74 kB │ gzip:   2.10 kB
dist/locales/generated/es-ES.js        4.77 kB │ gzip:   1.95 kB
dist/locales/generated/tr-TR.js        4.77 kB │ gzip:   2.07 kB
dist/locales/generated/de-DE.js        4.77 kB │ gzip:   2.02 kB
dist/locales/generated/ca-ES.js        4.80 kB │ gzip:   1.97 kB
dist/locales/generated/ko-KR.js        4.80 kB │ gzip:   2.20 kB
dist/locales/generated/ro-RO.js        4.80 kB │ gzip:   2.00 kB
dist/locales/generated/fr-FR.js        4.81 kB │ gzip:   1.97 kB
dist/locales/generated/hu-HU.js        4.89 kB │ gzip:   2.14 kB
dist/locales/generated/he-IL.js        4.95 kB │ gzip:   2.04 kB
dist/locales/generated/ja-JP.js        5.02 kB │ gzip:   2.24 kB
dist/locales/generated/vi-VN.js        5.26 kB │ gzip:   2.19 kB
dist/locales/generated/ar-SA.js        5.42 kB │ gzip:   2.26 kB
dist/locales/generated/pseudo-en.js    5.75 kB │ gzip:   2.32 kB
dist/locales/generated/sr-Cyrl.js      5.89 kB │ gzip:   2.37 kB
dist/locales/generated/uk-UA.js        6.18 kB │ gzip:   2.47 kB
dist/locales/generated/el-GR.js        6.54 kB │ gzip:   2.58 kB
dist/locales/generated/ru-RU.js        6.69 kB │ gzip:   2.60 kB
dist/index.js                        606.48 kB │ gzip: 160.10 kB
✓ built in 2.45s

——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 NX   Successfully ran target build for project twenty-emails and 2 tasks it depends on (5s)

Nx read the output from the cache instead of running the command for 2 out of 3 tasks.
```

Fixing folder to search for tsconfig from
2025-11-06 16:28:01 +00:00
GuillimandGitHub 373399fadc Settings of morph needs a CSS fix (#15681)
adding margin auto for morph preview card in order to vertically align
the box, as per figma

Before
<img width="467" height="331" alt="Screenshot 2025-11-06 at 16 36 00"
src="https://github.com/user-attachments/assets/23543cdc-d0f3-4bbf-8dc1-4ac5f26f786e"
/>

After
<img width="576" height="362" alt="Screenshot 2025-11-06 at 16 36 16"
src="https://github.com/user-attachments/assets/8530d59f-53a2-4eaa-834a-68b801bba3c8"
/>

Fixes https://github.com/twentyhq/core-team-issues/issues/1846
2025-11-06 17:06:04 +01:00
martmullandGitHub d1224e1c78 Fix wrong serverless handelrPath (#15675)
as title

After a sync hellp-world from twenty:
- before:

<img width="1052" height="321" alt="image"
src="https://github.com/user-attachments/assets/e008f2fd-f01e-405f-9ce0-1f14659157c6"
/>

- after:

<img width="1089" height="190" alt="image"
src="https://github.com/user-attachments/assets/3c9e301f-eabc-46e7-89e7-baf770dc0bc0"
/>
2025-11-06 16:31:29 +01:00
EtienneandGitHub 037663ddcd RichText editor fixes (#15678)
closes https://github.com/twentyhq/twenty/issues/15474
closes https://github.com/twentyhq/twenty/issues/15677
2025-11-06 16:21:57 +01:00
Abdullah.andGitHub 47a9b4ce9d fix: formidable relies on hexoid to prevent guessing of filenames for untrusted executable content (#15672)
Resolves [Dependabot Alert
224](https://github.com/twentyhq/twenty/security/dependabot/224) -
formidable relies on hexoid to prevent guessing of filenames for
untrusted executable content.

Used `yarn up formidable --recursive` to upgrade the version from 2.1.2
to 2.1.5.
2025-11-06 16:18:32 +01:00
neo773andGitHub 546fba7d05 [MESSAGING] Calendar check syncStatus in jobs (#15658) 2025-11-06 16:14:21 +01:00
neo773andGitHub dc57f00e26 register relaunch channels cron (#15662) 2025-11-06 16:14:06 +01:00
Baptiste DevessierandGitHub 9ec0a7b969 fix: use default trigger name if step name isn't defined (#15676)
## Before


https://github.com/user-attachments/assets/68427ca7-6523-4acc-bec3-7d98f3ae7840

## After


https://github.com/user-attachments/assets/8a998a52-29fc-450e-a92e-1cadc78e3856
2025-11-06 15:48:37 +01:00
Thomas TrompetteandGitHub e4ae792225 Allow rich text v2 in workflows (#15674)
Rich text V2 is supported and has probably been removed by mistake

Fix https://github.com/twentyhq/twenty/issues/15660
2025-11-06 14:33:06 +00:00
martmullandGitHub b00c36af16 Fix workspaceLogo in invite-email signed twice (#15673)
as title
2025-11-06 14:13:10 +00:00
Abdul RahmanandGitHub e518f03031 Fix: AI Agent tool errors and relation field handling (#15668)
### Problems Fixed

1. **Tool execution errors broke conversations**
- Failed tool executions showed "Processing..." indefinitely instead of
error messages
- Tool errors with `input: null` caused subsequent messages to fail with
`Missing required parameter: 'input[X].arguments'`

2. **Relation fields not saved in AI Agent**
- AI Agent couldn't save relation fields (e.g., `companyId`) when
creating/upserting records
   - Join column names weren't recognized during field validation

### Solutions

**Tool Error Handling:**
- Display error messages in UI with expandable error details
- Ensure tool parts always have valid `input` field (`input:
part.toolInput ?? {}`)
- Refactored `ToolStepRenderer` to accept complete `toolPart` object

**Relation Field Support:**
- Updated field validation in `create-record.service.ts` and
`upsert-record.service.ts`
- Check both `fieldIdByName` and `fieldIdByJoinColumnName` mappings

### Changes
- `packages/twenty-front/src/modules/ai/`
  - `ToolStepRenderer.tsx` - Error state handling
  - `AIChatAssistantMessageRenderer.tsx` - Pass complete toolPart
  - `mapDBPartToUIMessagePart.ts` - Prevent null tool input
- `packages/twenty-server/src/engine/core-modules/record-crud/services/`
  - `create-record.service.ts` - Add join column validation
  - `upsert-record.service.ts` - Add join column validation
2025-11-06 12:28:00 +01:00
Thomas TrompetteandGitHub 027e9dddd3 Increase main chunk size to 6.1MB (#15667)
As title
2025-11-06 10:38:08 +00:00
MarieandGitHub 3bb0eccf58 [Fix] fix getRoles for demo (#15666)
following https://github.com/twentyhq/twenty/pull/15547
2025-11-06 10:22:08 +00:00
8be56ee0cb i18n - translations (#15665)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-06 11:21:42 +01:00
Thomas TrompetteandGitHub 259c8cde08 Remove automated trigger update (#15663)
Automated triggers are duplicated on version update.
2025-11-06 10:01:24 +00:00
WeikoandGitHub 051a226b6f Fix display currency amount if currency code is empty string (#15654)
## Before
<img width="1306" height="841" alt="Screenshot 2025-11-05 at 18 40 05"
src="https://github.com/user-attachments/assets/964f5771-bd91-4cb2-9684-52073b845580"
/>


## After
<img width="1297" height="795" alt="Screenshot 2025-11-05 at 18 39 55"
src="https://github.com/user-attachments/assets/4ae99265-7459-4579-9f65-e2d8225e8306"
/>
2025-11-05 23:55:57 +01:00
MarieandGitHub 982964efbf Fix scroll to start when resize or move around columns (#15655)
Fixes https://github.com/twentyhq/private-issues/issues/361

There's room for more improvement here -
triggerInitialRecordTableDataLoad does a lot of things, should not be
triggered so much. actually even
RecordTableVirtualizedInitialDataLoadEffect should not be triggered when
there's just a metadata field change (if we trust the name
initialDataLoad)
2025-11-05 18:58:35 +01:00
martmullandGitHub abde3c04ac 1630 extensibility twenty cli ability to create edit and delete fields (#15501)
As title

- adds decorators in twenty-sdk
- update twenty-cli load-manifest to it gets @FieldMetadata infos +
testing
- update twenty-server so it CRUD fields properly, using
universalIdentifier
- Fix UI so we can update managed objects records
- move FieldMetadata items from twenty-server to twenty-shared
2025-11-05 17:50:06 +01:00
EtienneandGitHub 9fef0752a1 Fix subdomain generation at workspace creation (#15649) 2025-11-05 15:16:26 +00:00
f0aac163bd i18n - translations (#15644)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-05 14:49:51 +01:00
636c564168 Add shortcut on dashboard workspace entity + add shortcuts (#15603)
syncmetadata required!
closes
https://discord.com/channels/1130383047699738754/1435260594176393256

---------

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-11-05 13:42:37 +00:00
5dfb0dfc4b i18n - translations (#15642)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-05 14:39:49 +01:00
Abdullah.andGitHub da1399afcf fix: brace-expansion regular expression denial of service vulnerability (#15637)
Resolves [Dependabot Alert
238](https://github.com/twentyhq/twenty/security/dependabot/238) -
brace-expansion regular expression denial of service vulnerability.

This alert was closed yesterday, but `yarn.lock` went back to the
previous versions somehow when an unrelated PR was reverted. Therefore,
creating a PR again.

Versions on main:
<p align="center">
<img width="470" height="385" alt="image"
src="https://github.com/user-attachments/assets/69fb6519-21c0-4f69-9412-a7b05451cf57"
/>
</p>

Updated versions in the PR:
<p align="center">
<img width="472" height="383" alt="image"
src="https://github.com/user-attachments/assets/69f2a7c4-8015-4a92-8e25-1b8953f329da"
/>
</p>
2025-11-05 14:34:41 +01:00
1b0c158c88 i18n - translations (#15635)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-05 14:23:12 +01:00
Alex GaleyandGitHub 583d490cd7 feat: [Fireflies] log cleanly (#15618)
## [0.2.2] - 2025-11-04

### Added
- **Enhanced logging system**: Introduced configurable `AppLogger` class
with log level support (debug, info, warn, error, silent)
- Environment-based log level configuration via `LOG_LEVEL` environment
variable
  - Test environment detection to prevent log noise during testing
  - Context-aware logging with proper prefixes for better debugging
- **Improved error handling**: Enhanced webhook signature verification
with detailed debug logging
- **Better debugging capabilities**: Added comprehensive logging
throughout webhook processing pipeline

### Enhanced
- **Webhook signature verification**: Improved signature validation with
detailed logging for troubleshooting
- **Error messages**: More descriptive error logging for failed
operations and security violations
- **Development experience**: Better debugging information for webhook
processing and API interactions
2025-11-05 14:16:18 +01:00
Thomas TrompetteandGitHub f21b862d52 Set lambda timeout in service (#15632)
Some functions keep running without a timeout being thrown. Doing it in
service directly.
2025-11-05 12:43:23 +00:00
c294af2944 i18n - translations (#15634)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-05 11:36:35 +01:00
nitinandGitHub 3f52102e18 fix groupMode regression caused due to default value flip (#15627) 2025-11-05 16:04:09 +05:30
0fcfcec426 (Breaking change) Switch between set password and change password on the settings page. (#15582)
Here is what the PR does:

- Surface password state in validatePasswordResetToken, returning
hasPassword so the client can tell whether a user is setting or changing
their password.
- Consume that flag throughout the front end (mock data, stories,
GraphQL types) and update the Reset/Set Password modal to swap the
heading/button label and success toast accordingly.
- After a successful password set/reset, immediately update the
logged-in user’s hasPassword flag so the Settings screen reflects the
new state without a reload.

Modal has two states now - reset password modal uses change password
state since it made intuitive sense.

<p align="center">
<img width="404" height="397" alt="image"
src="https://github.com/user-attachments/assets/c54cc581-1248-4395-833d-0202758e1947"
/>
</p>

<p align="center">
<img width="403" height="393" alt="image"
src="https://github.com/user-attachments/assets/d8a39a95-27e6-4037-86f2-1f74176002ba"
/>
</p>

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-11-05 11:29:37 +01:00
Abdul RahmanandGitHub cc7343a8f2 Revert: Agent chat umbrella hook refactoring due to streaming issue on thread switch (#15621)
## Summary

Reverts commits afc518a, ae22e64, and 800b5b5 that refactored
`useAgentChat` to address umbrella hook pattern feedback.

## Issues Introduced by Refactoring

The refactoring broke several critical functionalities:

1. **Streaming fails on thread switch** - Messages don't stream properly
when switching between threads
2. **Messages lost on tab close** - When the Ask AI tab is closed, the
request is lost instead of continuing in the background
3. **Blank chat requiring force-reload** - Chats often appear blank and
require switching to another chat to force a reload (closes
[#1771](https://github.com/twentyhq/core-team-issues/issues/1771))

## Root Cause

After extensive debugging, it appears **multiple instances of `useChat`
don't work well together**. The refactored architecture inadvertently
created scenarios where multiple `useChat` instances interfere with each
other.

## Resolution

Reverting to restore functionality. The umbrella hook pattern
optimization needs a different architectural approach that doesn't rely
on multiple `useChat` instances.

## Follow-up

While the umbrella hook feedback is valid, we need to rethink the
implementation strategy:
- Find an alternative to multiple `useChat` instances
- Possibly consolidate chat state management differently
2025-11-05 10:50:50 +01:00
003b04e9ae fix: removeuseMergeRecordRelatationship and simplify dry run response (#15486)
## Description

- This PR addresses issue
https://github.com/twentyhq/twenty/issues/15201
- Removed
[useMergeRecordRelationships.ts](https://github.com/twentyhq/twenty/compare/main...harshit078:fix-merge-frontend?expand=1#diff-5d0366f814ff0c0e8961f40120690206a7acd3f7b66135cfb8c4ad8d3f6bc681)
- now backend returns populated result and frontend just shows it
without refetching relations.
- to be merged after PR- https://github.com/twentyhq/twenty/pull/15484


## Visual Appearance

 


https://github.com/user-attachments/assets/09d7548a-74a9-4742-af49-e98b4174f68c

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2025-11-05 10:33:24 +01:00
martmullandGitHub 642e0c882a Fix missing creation attributes (#15624) 2025-11-05 08:29:23 +00:00
neo773andGitHub 5d5999b80a fix useTriggerProviderReconnect (#15620) 2025-11-05 00:51:25 +01:00
6a8dcf8d8b i18n - translations (#15619)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-05 00:32:12 +01:00
neo773andGitHub 0b7271ad13 refactor reconnect account logic (#15584) 2025-11-05 00:26:23 +01:00
martmullandGitHub 5c3eaf7a10 Fix dependencies (#15617)
As title
2025-11-05 00:13:39 +01:00
martmullandGitHub 86a6e04d78 Fix hacktoberfest applications (#15613)
As title, make them syncable with twenty-cli:0.2.0
<img width="1025" height="693" alt="image"
src="https://github.com/user-attachments/assets/a18f8ba3-b6fc-40e9-84dd-446ff8deeb04"
/>
2025-11-04 18:40:06 +01:00
nitinandGitHub b5064e88f6 Fix groupMode toggle (#15585)
groupMode should be undefined if no groupby is set on the secondary
axis!
This default value is also the reason -- all the logic -- where
groupMode was checked for conditional rendering -- for eg
, negative data labels when there is no groupby -- the labels should
appear below wasn't happening -- since there was always a default to
groupMode!
changes - 
- getting rid of the default value on the bar chart DTO for groupMode
- on front -- make sure groupMode is only set when the secondary axis
gets groupBy id and proper cleanup
2025-11-04 18:28:20 +01:00
GuillimandGitHub e64603e61a release 1.10 flush cache command (#15610) 2025-11-04 17:29:06 +01:00
Raphaël BosiandGitHub 05a28a8ec2 Create a feature flag for dashboards v2 (#15601)
Prevent users from creating v2 chart types via the api.
Only created unit tests and not integration tests (since it's not that
important, and the v2 will be released soon), but tested via the api
playground.
2025-11-04 16:29:08 +01:00
martmullandGitHub 59f3f03539 Move browser-extension to proper folder (#15608)
As title
- move all applications and browser extension into a
`packages/twenty-apps/hacktoberfest-2025` folder
2025-11-04 15:28:09 +00:00
Thomas TrompetteandGitHub bff7901678 Set default run limit in cache (#15606)
Will be used when there are too many workflow runs to enqueue in
workspace
2025-11-04 16:23:46 +01:00
Nabhag MotivarasandGitHub e09b67158e [HACKTOBERFEST] LINKEDIN EXTENSION (#15521)
# Twenty Browser Extension


A Chrome browser extension for capturing LinkedIn profiles (people and
companies) directly into Twenty CRM. This is a basic **v0** focused
mostly on establishing a architectural foundation.

## Overview

This extension integrates with LinkedIn to extract profile information
and create records in Twenty CRM. It uses **WXT** as the framework -
initially tried Plasmo, but found WXT to be significantly better due to
its extensibility and closer alignment with the Chrome extension APIs,
providing more control and flexibility.

## Architecture

### Package Structure

The extension consists of two main packages:

1. **`twenty-browser-extension`** - The main extension package (WXT +
React)
2. **`twenty-apps/browser-extension`** - Serverless functions for API
interactions

### Extension Components

#### Entrypoints

- **Background Script** (`src/entrypoints/background/index.ts`)
  - Handles extension messaging protocol
  - Manages API calls to serverless functions
  - Coordinates communication between content scripts and popup

- **Content Scripts**
- **`add-person.content`** - Injects UI button on LinkedIn person
profiles
- **`add-company.content`** - Injects UI button on LinkedIn company
profiles
- Both scripts use WXT's `createIntegratedUi` for seamless DOM injection
  - Extract profile data from LinkedIn DOM

- **Popup** (`src/entrypoints/popup/`)
  - React-based popup UI
  - Displays extracted profile information
  - Provides buttons to save person/company to Twenty

#### Messaging System

Uses `@webext-core/messaging` for type-safe communication between
extension components:

```typescript
// Defined in src/utils/messaging.ts
- getPersonviaRelay() - Relays extraction from content script
- getCompanyviaRelay() - Relays extraction from content script
- extractPerson() - Extracts person data from LinkedIn DOM
- extractCompany() - Extracts company data from LinkedIn DOM
- createPerson() - Creates person record via serverless function
- createCompany() - Creates company record via serverless function
- openPopup() - Opens extension popup
```

#### Serverless Functions

Located in
`packages/twenty-apps/browser-extension/serverlessFunctions/`:

- **`/s/create/person`** - Creates a new person record in Twenty
- **`/s/create/company`** - Creates a new company record in Twenty
- **`/s/get/person`** - Retrieves existing person record (placeholder)
- **`/s/get/company`** - Retrieves existing company record (placeholder)

## Development Guide

### Prerequisites

- Twenty CLI installed globally: `npm install -g twenty-cli`
- API key from Twenty: https://twenty.com/settings/api-webhooks

### Setup
   ```
1. **Configure environment variables:**
   - Set `TWENTY_API_URL` in the serverless function configuration
- Set `TWENTY_API_KEY` (marked as secret) in the serverless function
configuration
- For local development, create a `.env` file or configure via
`wxt.config.ts`

### Development Commands

```bash
# Start development server with hot reload
npx nx run dev twenty-browser-extension

# Build for production
npx nx run build twenty-browser-extension

# Package extension for distribution
npx nx run package twenty-browser-extension
```

### Development Workflow

1. **Start the dev server:**
   ```bash
   npx nx run dev twenty-browser-extension
   ```
   This starts WXT in development mode with hot module reloading.

2. **Load extension in Chrome:**
   - Navigate to `chrome://extensions/`
   - Enable "Developer mode"
   - Click "Load unpacked"
   - Select `packages/twenty-browser-extension/dist/chrome-mv3-dev/`

3. **Test on LinkedIn:**
- Navigate to a LinkedIn person profile:
`https://www.linkedin.com/in/...`
- Navigate to a LinkedIn company profile:
`https://www.linkedin.com/company/...`
   - The "Add to Twenty" button should appear in the profile header
   - Click the button to open the popup and save to Twenty

### Project Structure

```
packages/twenty-browser-extension/
├── src/
│   ├── common/
│   │   └── constants/      # LinkedIn URL patterns
│   ├── entrypoints/
│   │   ├── background/     # Background service worker
│   │   ├── popup/          # Extension popup UI
│   │   ├── add-person.content/  # Content script for person profiles
│   │   └── add-company.content/ # Content script for company profiles
│   ├── ui/                 # Shared UI components and theme
│   └── utils/              # Messaging utilities
├── public/                 # Static assets (icons)
├── wxt.config.ts          # WXT configuration
└── project.json            # Nx project configuration
```

## Current Status (v0)

This is a foundational version focused on architecture. Current
features:

 Inject UI buttons into LinkedIn profiles
 Extract person and company data from LinkedIn
 Display extracted data in popup
 Create person records in Twenty
 Create company records in Twenty

## Planned Features

- [ ] Provide a way to have API key and custom remote URLs.
- [ ] Detect if record already exists and prevent duplicates
- [ ] Open existing Twenty record when clicked (instead of creating
duplicate)
- [ ] Sidepanel Overlay UI for rich profile viewing/editing
- [ ] Enhanced data extraction (email, phone, etc.)
- [ ] Better error handling

# Demo


https://github.com/user-attachments/assets/0bbed724-a429-4af0-a0f1-fdad6997685e



https://github.com/user-attachments/assets/85d2301d-19ee-43ba-b7f9-13ed3915f676
2025-11-04 15:52:06 +01:00
Raphaël BosiandGitHub 06f5ac63dc Add dashboards lab image (#15605)
<img width="800" height="500" alt="is-dashboard-enabled"
src="https://github.com/user-attachments/assets/9b7f09ff-54f2-4026-b2a8-8d0a9ea1a98b"
/>
2025-11-04 15:44:46 +01:00
cd05470e99 i18n - translations (#15602)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-04 15:36:08 +01:00
Paul RastoinandGitHub 8dd43be9a2 Create many view groups (#15591)
# Introduction
Same as https://github.com/twentyhq/twenty/pull/15576 but for view
groups creation

When creating a kanban view with v2 flag activated in production result
in race condition due to request being slow and //.
That's why we're introducing a batch create on view group here
closing https://github.com/twentyhq/core-team-issues/issues/1847

## In v2
- batch create view group endpoint is available
- frontend will target the new endpoint

## In v1
- batch create view group endpoint is not available
- frontend will stick to old fake batch view group creation loop


## Gallery
### v2
<img width="1796" height="486" alt="image"
src="https://github.com/user-attachments/assets/932cfe9f-85f1-41cc-a1c4-72a4b5d5a256"
/>

### v1
<img width="1852" height="966" alt="image"
src="https://github.com/user-attachments/assets/8aa9df11-cdea-4b12-ae60-118cdf5e257b"
/>
2025-11-04 15:17:55 +01:00
558990fbdd i18n - translations (#15600)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-04 15:13:13 +01:00
martmullandGitHub 89c8d89330 Revert "Revert "[hacktoberfest] feat: add fireflies"" (#15595)
Reverts twentyhq/twenty#15589

Add back without the breaking change
2025-11-04 15:07:30 +01:00
nitinandGitHub 186dbb8aca fast-follows: fix placeholder not appearing when no widgets in a tab (#15599)
closes -
https://discord.com/channels/1130383047699738754/1435261256251605053

before:


https://github.com/user-attachments/assets/fbbfd6b0-6c25-48c3-9367-efbf47efd34a

after:


https://github.com/user-attachments/assets/87105c4e-cf79-43c0-83bb-ebb4c32a64fc
2025-11-04 14:05:02 +00:00
neo773andGitHub e3076328dd Child folders followup (#15526) 2025-11-04 15:04:03 +01:00
15a6ca64da i18n - translations (#15598)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-04 14:40:04 +01:00
Paul RastoinandGitHub 1472eb3cda [Twenty-front] Jest maxWorkers 50% as if not result to cpu halt (#15594) 2025-11-04 14:35:35 +01:00
Raphaël BosiandGitHub 7256abad3a Dashboard: Deactivate delete and navigation actions in edit mode (#15590)
https://github.com/user-attachments/assets/74256232-dfb1-4cb5-9fd8-854e0b3b7c09
2025-11-04 18:43:36 +05:30
Paul RastoinandGitHub 3514054235 V2 centralize relation optimistic logic (#15552)
# Introduction
This PR aims to deprecate having to manually handle optimistic side
effect foreign key addition in the whole v2 experience.
This PR implements the strong basis + builder refactor of the optimistic
computation of a given flat entity maps with its related flat entity
maps ( runner needs a small refactor on actions type definition first )
Flat entity maps updates through mutations are now only scoped to the
generic entity builder ( very isolated )

## What's next
- Refactor actions v2 type definition to gain grain over `metadataName`
and action operation ( `create` `delete` `update` ).
from `{type: 'create_view_field'}` to `{metadataName: 'view_field',
type: 'create' }`
- Use new optimistic tool computation tools
- Only invalidate impacted flat maps cache

## New tools
Strictly dynamically typed new flat entity maps tools
- `addFlatEntityToFlatEntityAndRelatedEntityMapsThroughMutationOrThrow`
-
`deleteFlatEntityFromFlatEntityAndRelatedEntityMapsThroughMutationOrThrow`

## Unit test
Adding basic unit testing coverage to introduced tools

## `FlatEntityValidationArgs`
From 
```ts
export type FlatEntityValidationArgs<T extends AllMetadataName> = {
  flatEntityToValidate: MetadataFlatEntity<T>;
  optimisticFlatEntityMaps: MetadataFlatEntityMaps<T>;
  mutableDependencyOptimisticFlatEntityMaps: MetadataValidationRelatedFlatEntityMaps<T>;
  workspaceId: string;
  remainingFlatEntityMapsToValidate: MetadataFlatEntityMaps<T>;
  buildOptions: WorkspaceMigrationBuilderOptions;
};

```

To
```ts
export type FlatEntityValidationArgs<T extends AllMetadataName> = {
  flatEntityToValidate: MetadataFlatEntity<T>;
  optimisticFlatEntityMapsAndRelatedFlatEntityMaps: MetadataFlatEntityAndRelatedFlatEntityMapsForValidation<T>;
  workspaceId: string;
  remainingFlatEntityMapsToValidate: MetadataFlatEntityMaps<T>;
  buildOptions: WorkspaceMigrationBuilderOptions;
};

```
2025-11-04 12:28:28 +01:00
WeikoandGitHub 281070423f Revert "[hacktoberfest] feat: add fireflies" (#15589)
Reverts twentyhq/twenty#15527 due to tsconfig base update
2025-11-04 12:25:23 +01:00
Yannik SüßandGitHub ad80a50354 feat: add Webmetic Visitor Intelligence (#15551)
# Webmetic Visitor Intelligence

Automatically sync B2B website visitor data into Twenty CRM. Identify
anonymous companies visiting your website and track their engagement
without forms or manual entry. Every hour, Webmetic enriches your CRM
with actionable sales intelligence about who's researching your product
before they ever fill out a contact form.

## Features

- 🔄 **Hourly Automatic Sync**: Fetches visitor data every hour via cron
trigger
- 🏢 **Company Enrichment**: Creates and updates company records with
visitor intelligence
- 📊 **Website Lead Tracking**: Records individual visits with detailed
engagement metrics
- 📈 **Engagement Scoring**: Webmetic's proprietary scoring algorithm
(0-100) identifies warm leads
- 🎯 **Sales Intelligence**: See which companies are actively researching
your product
- 🌍 **Geographic Data**: Captures visitor city and country information
- 🔗 **UTM Parameter Tracking**: Full campaign attribution with
utm_source, utm_medium, utm_campaign, utm_term, and utm_content
- 📄 **Page Journey Mapping**: Records complete navigation paths and
scroll depth
-  **Smart Deduplication**: Prevents duplicate records using
session-based identification
- 🔐 **Production-Ready**: Built with rate limiting, error handling, and
idempotent operations

## Requirements

- `twenty-cli` — `npm install -g twenty-cli`
- A Twenty API key (create one at
`https://twenty.com/settings/api-webhooks` and name it **"Webmetic"**)
- A Webmetic account with API access. Sign up at
[webmetic.de](https://webmetic.de)
- Node 18+ (for local development)

## Metadata prerequisites

The app automatically creates the `websiteLead` custom object with all
required fields on first run. No manual field provisioning is needed.

**Created automatically:**
- `websiteLead` object with 14 custom fields (TEXT, NUMBER, DATE_TIME
types)
- Company relation field (Many-to-One from websiteLead to Company)
- All fields are idempotent — safe to re-run without errors

## Quick start

### 1. Deploy the app

```bash
twenty auth login
cd packages/twenty-apps/webmetic
twenty app sync
```

### 2. Configure environment variables

- **First, create a Twenty API key**:
  - Go to **Settings → API & Webhooks → API Keys**
  - Click **+ Create API Key**
  - Name it **"Webmetic"**
  - Copy the generated key
- **Then configure the app**:
- Open **Settings → Apps → Webmetic Visitor Intelligence →
Configuration**
  - Provide values for the required keys:
- `TWENTY_API_KEY` (required secret; paste the API key you just created)
- `TWENTY_API_URL` (optional; defaults to `http://localhost:3000` for
local dev, set to your production URL)
- `WEBMETIC_API_KEY` (required secret; get from
[app.webmetic.de/?menu=api_details](https://app.webmetic.de/?menu=api_details))
- `WEBMETIC_DOMAIN` (required; your website domain to track, e.g.,
`example.com`)
  - Save the configuration

### 3. Test the function

- On the app page, select **Test your function**
- Click **Run**
- You should see a success summary showing companies and leads created
- Check **Settings → Data Model → Website Leads** to verify the custom
object was created
- Navigate to **Website Leads** from the sidebar to view synced visitor
data

### 4. Automatic hourly sync begins

The cron trigger (`0 * * * *`) runs every hour on the hour, continuously
syncing new visitor data.

## How it works

### Data flow

```
Webmetic API ─[hourly]→ sync-visitor-data ─[create/update]→ Twenty CRM
                              │
                              ├─→ Company records (with enrichment data)
                              └─→ Website Lead records (linked to companies)
```

### Sync process

1. **Cron Trigger**: Every hour at :00 (e.g., 1:00, 2:00, 3:00)
2. **Schema Validation**: Ensures `websiteLead` object and all fields
exist (creates if missing)
3. **Fetch Visitors**: Queries Webmetic API `/company-sessions` endpoint
for last hour
4. **Process Companies**: For each visitor's company:
   - Searches for existing company by domain
- Creates new company or updates existing with latest data from Webmetic
   - Extracts employee count from ranges (e.g., "11-50" → 50)
5. **Create Website Leads**: For each session:
   - Checks for duplicate (by name: "Company - Date")
   - Creates lead record with engagement metrics
   - Links to company via relation field
6. **Rate Limiting**: 800ms delay between API calls (75 requests/minute
max)

### Data captured

**Company enrichment (from Webmetic):**
- Name, domain, address (street, city, postcode, country)
- Employee count (parsed from ranges)
- LinkedIn URL (if available)
- Tagline/short description

**Website Lead tracking:**
- Visit date and session duration
- Page views count and pages visited (full navigation path)
- Traffic source (Direct, or utm_source/utm_medium combination)
- UTM campaign parameters (campaign, term, content)
- Visitor location (city, country)
- Engagement score (Webmetic's 0-100 scoring)
- Average scroll depth percentage
- Total user interaction events (clicks, etc.)

## Configuration reference

| Variable | Required | Description |
|----------|----------|-------------|
| `TWENTY_API_KEY` |  Yes | Your Twenty API key for authentication |
| `TWENTY_API_URL` |  No | Base URL of your Twenty instance (defaults
to `http://localhost:3000`) |
| `WEBMETIC_API_KEY` |  Yes | Your Webmetic API key from
[app.webmetic.de/?menu=api_details](https://app.webmetic.de/?menu=api_details)
|
| `WEBMETIC_DOMAIN` |  Yes | Website domain to track (e.g.,
`example.com` without protocol) |

## API integration

This app uses multiple Twenty CRM APIs:

**REST API** (data operations):
- `GET /rest/metadata/objects` — Fetch object metadata with fields
- `GET /rest/companies` — Find existing companies by domain
- `POST /rest/companies` — Create new companies
- `PATCH /rest/companies/:id` — Update company data
- `POST /rest/websiteLeads` — Create website lead records

**GraphQL Metadata API** (schema management):
- `createOneObject` mutation — Creates custom objects (if needed)
- `createOneField` mutation — Creates custom fields and relations

## Website Lead object structure

The app creates a custom `websiteLead` object with the following fields:

| Field | Type | Description |
|-------|------|-------------|
| `name` | TEXT | Lead identifier (Company Name - Date) |
| `company` | RELATION | Many-to-One relation to Company object |
| `visitDate` | DATE_TIME | When the visit occurred |
| `pageViews` | NUMBER | Number of pages viewed during session |
| `sessionDuration` | NUMBER | Visit length in seconds |
| `trafficSource` | TEXT | Where visitor came from
(utm_source/utm_medium or Direct) |
| `pagesVisited` | TEXT | List of page URLs visited (→ separated, max
1000 chars) |
| `utmCampaign` | TEXT | UTM campaign parameter |
| `utmTerm` | TEXT | UTM term parameter (keywords for paid search) |
| `utmContent` | TEXT | UTM content parameter (for A/B testing) |
| `visitorCity` | TEXT | Geographic city of visitor |
| `visitorCountry` | TEXT | Geographic country of visitor |
| `visitCount` | NUMBER | Total number of visits from this company |
| `engagementScore` | NUMBER | Webmetic engagement score (0-100) |
| `averageScrollDepth` | NUMBER | Average scroll percentage (0-100) |
| `totalUserEvents` | NUMBER | Total count of user interactions (clicks,
etc.) |

## Troubleshooting

**Issue**: No data syncing after setup
- **Solution**: Run "Test your function" to manually trigger a sync and
check logs. Verify your `WEBMETIC_API_KEY` and `WEBMETIC_DOMAIN` are
correct.

**Issue**: "Duplicate Domain Name" error
- **Solution**: This occurs if you previously deleted a company. Twenty
maintains unique constraints on soft-deleted records. Either restore the
company from trash or contact support.

**Issue**: Missing fields on websiteLead object
- **Solution**: The sync function recreates missing fields
automatically. Run "Test your function" once to repair the schema.

**Issue**: Empty linkedinLink on companies
- **Solution**: Webmetic doesn't have LinkedIn data for that specific
company. The mapping is working correctly; data availability depends on
Webmetic's enrichment coverage.

**Issue**: Employee count not matching Webmetic
- **Solution**: Webmetic returns ranges (e.g., "11-50"). The app uses
the maximum value (50) to better represent company size.

**Issue**: Test shows "No new visitors in the last hour"
- **Solution**: Normal if you have no traffic in the last 60 minutes.
Wait for actual traffic or manually adjust the time range in code for
testing.

## Rate limiting and performance

- **Webmetic API**: No pagination used; fetches all visitors from last
hour
- **Twenty API**: 800ms delay between requests (75 requests/minute)
- **Processing**: Handles 14+ companies with full enrichment in under 30
seconds
- **Cron schedule**: `0 * * * *` (every hour on the hour)
- **Duplicate prevention**: Checks existing leads by name before
creating

## Development

### Local testing

```bash
cd packages/twenty-apps/webmetic
yarn install

# Set up .env file
cp .env.example .env
# Edit .env with your credentials

# Sync to local Twenty instance
npx twenty-cli app sync

# Watch for changes
npx twenty-cli app dev
```

### Manual trigger

Use the Twenty UI test panel or trigger via API:

```bash
curl -X POST http://localhost:3000/functions/sync-visitor-data \
  -H "Authorization: Bearer YOUR_API_KEY"
```

## Architecture notes

- **100% programmatic schema**: Fields created via GraphQL Metadata API,
not manifests
- **Idempotent operations**: Safe to re-run without duplicates or errors
- **Smart domain matching**: Normalizes domains (strips www, protocols)
for matching
- **Error resilience**: Individual company failures don't stop the
entire sync
- **Detailed logging**: Returns full execution log in response for
debugging

## Contributing

Built with 🍺 and ❤️ in Munich by [Team Webmetic](https://webmetic.de)
for Twenty CRM Hacktoberfest 2025.

For issues or questions:
- Webmetic API: [webmetic.de](https://webmetic.de)
- Twenty CRM: [twenty.com/developers](https://twenty.com/developers)

## License

MIT
2025-11-04 12:10:11 +01:00
Alex GaleyandGitHub 995f5b3b3f [hacktoberfest] feat: add fireflies (#15527) 2025-11-04 12:09:53 +01:00
BOHEUSandGitHub 6065fa61c7 Stripe synchronizer extension (#15515)
Challenge 7 from "Call for projects" list
2025-11-04 12:09:26 +01:00
Raphaël BosiandGitHub 98180c263d Filter out null values in tooltip (#15588)
Before:
<img width="356" height="330" alt="CleanShot 2025-11-04 at 11 44 14@2x"
src="https://github.com/user-attachments/assets/924f8623-3961-411c-9763-800fd9491224"
/>

After:
<img width="418" height="242" alt="CleanShot 2025-11-04 at 11 43 49@2x"
src="https://github.com/user-attachments/assets/54cf5fa4-1146-43b4-8cff-59817bcbe6a4"
/>
2025-11-04 11:09:12 +00:00
BOHEUSandGitHub ff1a87080a Mailchimp synchronizer extension (#15512)
Challenge 10 from "Call for projects" list
2025-11-04 12:05:51 +01:00
BOHEUSandGitHub e4dbe87fa1 Last email interaction extension (#15511)
Challenge 4 from "Call for projects" list
2025-11-04 12:05:22 +01:00
Ali IlmanandGitHub 1957f839ff [HACKTOBERFEST] [FEATURE] Create activity summary application (#15510)
## Background
This is team Comfortably Summed's submission for Twenty's Hacktoberfest.
We built an activity summary application that can periodically send
messages to the following platforms: Slack; Discord; and WhatsApp.
### Features
- 🧑‍💻 **People & Company Tracking**: Summarizes newly created people and
companies
- 🎯 **Opportunity Monitoring**: Reports on new opportunities created,
broken down by stage
-  **Task Analytics**:
  - Tracks task creation
  - Calculates on-time completion rates
  - Identifies team members with the most overdue tasks (the "slackers")
- 🔔 **Multi-Platform Notifications**: Send reports to Slack, Discord,
and/or WhatsApp
-  **Configurable Time Range**: Look back any number of days
### Summary of Changes
- Adds a new Twenty app called Activity Summary
- Contains a single index.ts file which utilises exported functions from
opportunity-creation-summariser.ts, people-creation-summariser.ts,
task-creation-summariser.ts, and senders.ts
- Implementation of sending a message to Slack, Discord, and WhatsApp
can be found in senders.ts
- Retrieval and summarising of Opportunity creation can be found in
opportunity-creation-summariser.ts
- Retrieval and summarising of People creation can be found in
people-creation-summariser.ts
- Retrieval and summarising of Task creation can be found in
task-creation-summariser.ts
## Screenshots
### Message to our Slack channel
<details>
<summary>Screenshot</summary>

<img width="326" height="242" alt="Screenshot 2025-11-01 at 22 05 30"
src="https://github.com/user-attachments/assets/57c5d50b-959d-4c3f-bd7d-00f42bf545b2"
/>
</details>

### Message to our Discord server's channel
<details>
<summary>Screenshot</summary>

<img width="472" height="386" alt="Screenshot 2025-11-01 at 22 06 44"
src="https://github.com/user-attachments/assets/f4a38d7f-e82d-47b0-a4b3-7bcf063fa575"
/>
</details>

### Message to our WhatsApp number
<details>
<summary>Screenshot</summary>
<img width="972" height="548" alt="IMG_2024"
src="https://github.com/user-attachments/assets/5533fc4d-a3ee-4e11-a9e7-9cc6a96316fc"
/>

</details>

### App-level configuration
<details>
<summary>Screenshot</summary>

<img width="442" height="385" alt="Screenshot 2025-11-01 at 22 02 14"
src="https://github.com/user-attachments/assets/c9948f57-f22c-42a0-972f-3348f480aa30"
/>
</details>

### Serverless functions
<details>
<summary>Screenshot</summary>

<img width="413" height="378" alt="Screenshot 2025-11-01 at 22 03 48"
src="https://github.com/user-attachments/assets/d297967b-52ce-4690-bb04-a16d89729d94"
/>
</details>

### Cron configuration
Default value in place due to Cron having a non-editable text input.
<details>
<summary>Screenshot</summary>

<img width="395" height="386" alt="Screenshot 2025-11-01 at 22 08 03"
src="https://github.com/user-attachments/assets/a95a708c-7136-4512-99c3-a6723adc0da5"
/>
</details>

## Testing
Sync the application to your Twenty instance and ensure the following
variables have values:
- `TWENTY_API_KEY` - Your Twenty CRM API key
- `DAYS_AGO` - Number of days to look back for the report

Choose any of the supported platforms and you shall see a summary being
sent!
2025-11-04 12:04:59 +01:00
7f3af243c7 [Hacktoberfest] AI-Powered Meeting Transcript Analysis Extension for Twenty CRM (#15507)
# 🧠 AI-Powered Meeting Transcript to CRM Data Integration

## **Overview**
This feature automatically transforms meeting transcripts into
structured CRM data using AI.
When unstructured meeting notes are received via a **webhook**, the
system processes them and creates organized **notes, tasks, and
assignments** directly in **Twenty CRM**.

---

## **Key Features**

- **🤖 AI-Powered Analysis:**  
Extracts **summaries, action items, assignees, and due dates** from
natural language transcripts.

- **📋 Smart Task Consolidation:**  
  Merges related sub-tasks into unified deliverables  
  *(e.g., `"draft" + "review" + "present"` → one consolidated task).*

- **👥 Intelligent Assignment:**  
Uses **GraphQL member lookup** to match extracted assignee names to
workspace member IDs with flexible string matching.

- **🔗 Automatic Linking:**  
Links generated **notes and tasks** to relevant contacts using
`noteTargets` and `taskTargets`.

- **🗓️ Date Parsing:**  
Converts **relative date expressions** (e.g., “next Monday”, “end of
week”) into **ISO-formatted dates** for accurate scheduling.

---

## **Technical Stack**

| Component | Description |
|------------|-------------|
| **AI Provider** | Groq (via OpenAI SDK) using the `GPT-OSS-20B` model
|
| **APIs** | Twenty CRM REST API + GraphQL (for member resolution) |
| **Runtime** | Webhook-triggered **serverless function** written in
**TypeScript** |

---

## **Example Input**

```json
{
  "transcript": "During the Project Phoenix Kick-off on November 1st, 2025, we discussed securing the Series B funding. ACTION: Dylan Field is designated to finalize the investor deck layout and needs to present it next Monday, November 4th. Irfan Hussain will review the deck before the presentation by Monday morning. COMMITMENT: Dario Amodei confirmed he would personally review the security protocols for the AI model before the end of this week, by Friday November 7th. Iqra Khan will coordinate the security review process and ensure completion by the Friday deadline.",
  "meetingTitle": "Project Phoenix Kick-off",
  "meetingDate": "2025-11-01",
  "participants": [
    "Brian Chesky",
    "Dario Amodei",
    "Iqra Khan",
    "Irfan Hussain",
    "Dylan Field"
  ],
  "token": "e6d9d54e51953fd5a451cca933c63e7f8783b001f0c45be95be9d09ee06c6cda",
  "relatedPersonId": "6c4b0e98-b69e-42a4-ba0c-fd2eeafca642"
}
```
---

## **Example Output**

```json
{
  "success": true,
  "noteId": "9cc3b4fc-ae37-4b3e-a343-a4c69cf6b1e8",
  "taskIds": [
    "0f408062-0dcc-49f0-9866-1ea05392661d",
    "2b3739bf-0653-4101-9419-6a44ea5135cd"
  ],
  "summary": {
    "noteCreated": true,
    "tasksCreated": 2,
    "actionItemsProcessed": 2,
    "commitmentsProcessed": 0
  },
  "executionLogs": [
    " Validation passed",
    "📝 RelatedPersonId: 6c4b0e98-b69e-42a4-ba0c-fd2eeafca642",
    "🤖 Starting transcript analysis...",
    " Analysis complete: 2 action items, 0 commitments",
    "📄 Creating note in Twenty CRM...",
    " Note created: 9cc3b4fc-ae37-4b3e-a343-a4c69cf6b1e8",
    "📋 Creating tasks from action items...",
    " Action item tasks created: 2",
    "📋 Creating tasks from commitments...",
    " Commitment tasks created: 0"
  ]
}
```
---

Variable Name | Description
-- | --
GROQ_API_KEY | API key for authenticating requests to the Groq AI
service.
TWENTY_API_KEY | Authentication token used to access the Twenty CRM API.
TWENTY_API_URL | Base URL for the Twenty CRM REST API.
WEBHOOK_SECRET | Secret key used to validate incoming webhook requests
for security.
NODE_ENV | Defines the runtime environment (development, production,
etc.).
LOG_LEVEL | Controls verbosity of logs (info, debug, error).

---

## **Attachments**
<img width="649" height="863" alt="swappy-20251103-035128"
src="https://github.com/user-attachments/assets/2f0390af-9538-4fe2-bba8-f38e558935ad"
/>

---




https://github.com/user-attachments/assets/88620035-67ed-4150-b0be-46131083e2c5



---

Co-authored-by: iqra77818 <iqra77818@gmail.com>
2025-11-04 12:04:00 +01:00
Harshit VashishtandGitHub 0cdc61c211 [HACKTOBERFEST] feat: Add AI meeting transcript integration with Twenty CRM (#15498)
This PR introduces an end-to-end workflow to automatically process
meeting transcripts and create structured notes and tasks in Twenty CRM.
It leverages OpenAI to extract summaries, key points, action items, and
participant commitments from transcripts.

Key features include:
1. AI-powered transcript analysis: Uses OpenAI GPT‑4o-mini to extract a
concise summary, key discussion points, action items, and commitments.
2. Automated note creation: Generates a rich Markdown note in Twenty CRM
with summary and key points.
3. Task automation: Automatically creates tasks in Twenty CRM from
extracted action items and commitments, linking them to the meeting
note.
4. Custom field support: Supports optional metadata from transcript
payloads, which can be included in note/task content or mapped to custom
fields in Twenty CRM if supported.
5. Webhook-ready: Designed to process Granola-style (or similar) webhook
payloads, making it easy to integrate with any AI meeting tool.





Sumbission for Hacktoberfest 
Team Name : One for All
2025-11-04 12:03:32 +01:00
James BryantandGitHub 7ec56433c7 [HACKTOBERFEST] Add rollup engine app with UI-driven configuration (#15482)
## Summary

- add packages/twenty-apps/rollup-engine: a parameterised rollup engine
that ships a default Opportunity → Company
    aggregation.
- declare runtime config in package.json (TWENTY_API_KEY, optional
TWENTY_API_BASE_URL, and ROLLUP_ENGINE_CONFIG) so
app configuration lives entirely in Settings → Apps → [App] →
Configuration.
- document the workflow in README.md: deploy via twenty app sync,
populate env vars in the UI, use the Test panel with
    a ready JSON payload, and reference troubleshooting tips.
- adjust the function entry point to a named async export and add
fallback logic for blank base URLs, matching the
    UI’s env behaviour.
- prune legacy templates and examples so
config/templates/opportunity-to-company.json is the single copy/paste
    starting point.

  ## UI / UX impact

  After syncing the app:

- the Configuration screen shows the three env keys with helpful
descriptions (API key, optional base URL, JSON
    override),
  - the built-in Test your function panel works immediately
- and the default JSON config is available from
config/templates/opportunity-to-company.json for users who need to
    customise rollups.

  ## Testing

  - Out-of-the-box deploy to the hosted workspace (Opportunity update) ✓
  - “Test your function” with the default config ✓
- Override example: point debugOpportunityCount at a scratch field via
ROLLUP_ENGINE_CONFIG ✓
  - Optional: local smoke test (yarn install && yarn smoke) still passes
2025-11-04 12:03:00 +01:00
WeikoandGitHub fd5c39b4da Remove default feature flag feature (#15587)
## Context
Having rollout feature for new workspaces creates bad experience for new
users and doesn't bring as much value as existing ones anyway. Removing
migration v2 from default feature flag and the whole concept of default
feature flag
2025-11-04 11:40:49 +01:00
Paul RastoinandGitHub a3dc6e5c59 View field create many mutation (#15576)
# Introduction
When creating a view with v2 flag activated in production result in race
condition due to request being slow and //.
That's why we're introducing a batch create on view field here
closing https://github.com/twentyhq/core-team-issues/issues/1836

## In v2
- batch create view field endpoint is available
- frontend will target the new endpoint

## In v1
- batch create view field endpoint is not available
- frontend will stick to old fake batch view field creation loop

## Polish
- use persist view field is quite verbose as contains two data model we
could aim to create an update many view fields in order to standardize
new pattern
2025-11-04 11:36:08 +01:00
nitinandGitHub 106c33abec fix inconsistent widget placeholder placement (#15580)
fixes -
https://github.com/twentyhq/twenty/pull/15496#issuecomment-3481636780

and https://discord.com/channels/1130383047699738754/1434971632539009055

- make the pending placeholder to be non-static -- so that it behaves
similarly to compact behavior like other widgets do
- make sure users can't set dashboards to be opened in the side panel --
similar to workflows

before- 


https://github.com/user-attachments/assets/d991db56-1388-4e4b-b743-a63f56b6187a

after- 


https://github.com/user-attachments/assets/9031f2c6-1e3b-4604-a5a0-3124d14484ce
2025-11-04 11:07:57 +01:00
Abdullah.andGitHub 77f04e7306 fix: brace-expansion regular expression denial of service vulnerability (#15558)
Resolves [Dependabot Alert
236](https://github.com/twentyhq/twenty/security/dependabot/236) and
[Dependabot Alert
237](https://github.com/twentyhq/twenty/security/dependabot/237).

Used `yarn up brace-expansion --recursive` to move versions from 1.1.11
and 2.0.1 to 1.1.12 and 2.0.2.
2025-11-04 08:53:57 +01:00
Abdullah.andGitHub 14c66c942f fix: update tmp to a safer version. (#15554)
@charlesBochet had a conversation with Felix and he said we don't need
to spend time upgrading `zapier-platform-core` and `zapier-platform-cli`
since `twenty-zapier` will be deprecated anyway, making those packages
irrelevant.

I have updated tmp to a safer version elsewhere using `yarn up tmp
--recursive`. Also added `yarn.lock` to both server and front ci.

The massive changes in `yarn.lock` were introduced by
`zapier-platform-cli` version 17x - not sure if they caused those
breaking changes, but if they did and we still want update
zapier-related packages, I will take that up in another PR.
2025-11-04 08:53:33 +01:00
Charles BochetandGitHub 7ff91a61c6 Add dashboard rollout commands (#15567)
## Tests

### makeSureDashboardNamingAvailableCommand

Case 1: no dashboard custom object
Case 2: with dashboard custom object

### SeedDashboardViewCommand

Case 1: no existing view
Case 2: with existing view
2025-11-03 18:35:57 +01:00
nitinandGitHub 5bc876e4b4 IFrame widget improvements (#15483)
changes - 
- make iframe side panel to match others -- ie use SidePanelHeader for
title
- make url optional in configuration to match that of the other widgets
(allow partial saves) - render No data status when error or no url
- split widget sizes into two -- graph widget sizes and widget sizes
(graph widgets are a subset of chart widgets)
2025-11-03 17:30:06 +00:00
902eb2c5d2 Instant widget placeholder placement on drag end (#15496)
closes -
https://discord.com/channels/1130383047699738754/1430596561137700957

fixed a bug - where on chart type change in side panel -- wont update
the widgets minimum size

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-03 17:08:13 +00:00
Thomas TrompetteandGitHub 9c695cfed5 Remove relations from manual trigger output schema (#15578)
Fixes https://github.com/twentyhq/twenty/issues/15319
Fixes https://github.com/twentyhq/twenty/issues/15255

On index page, we load record with only a few relation fields. So record
selected on manual trigger do not contain all the fields. To match that
behavior, let's remove relations from output schema. The user will do a
search on relation id if needed.
2025-11-03 16:54:13 +00:00
Raphaël BosiandGitHub 711cf819e9 Fix date granularity saving issue (#15579)
The date granularities were missing in the fragment
2025-11-03 16:53:44 +00:00
Lucas BordeauandGitHub b33b38cb02 Follow-up high fixes on date refactor (#15553)
This PR fixes important bugs on date filter handling following-up date
refactor.

Fixes : https://github.com/twentyhq/core-team-issues/issues/1814
2025-11-03 17:51:42 +01:00
nitinandGitHub bafc0496b1 add inner padding on bar chart (#15577)
before:

<img width="602" height="407" alt="CleanShot 2025-11-03 at 22 06 45"
src="https://github.com/user-attachments/assets/3553d3a0-2626-4f88-9adc-7d472fde2b26"
/>

after:

<img width="628" height="392" alt="CleanShot 2025-11-03 at 22 06 08"
src="https://github.com/user-attachments/assets/d5cf2b68-c5eb-4ce7-be27-c685ccd81109"
/>
2025-11-03 17:48:57 +01:00
a64d4dbe71 Various font styling fixes on chart (#15572)
- Fix axis legends styling
- Fix legends styling
- Fix tooltip legends

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-11-03 16:43:28 +00:00
6675931100 i18n - translations (#15574)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-03 17:36:59 +01:00
Raphaël BosiandGitHub 4a87706d0b Fix chart filter settings back button behavior (#15573)
Before:


https://github.com/user-attachments/assets/23881978-3234-4a0b-95ec-15470d26026d


After:


https://github.com/user-attachments/assets/80d222f6-585a-4fff-8476-dae327e34699
2025-11-03 16:25:59 +00:00
Thomas TrompetteandGitHub d1330a4a8c Improve workflow performances (#15528)
- on draft creation, do not fetch the full version. Avoid the fetch of
steps and trigger
- on activation, we were performing 8 queries/mutations synchronously +
2 additional for automated triggers. I refacto the call it it gets
reduced to 4 queries/mutations + 2 additional for automated triggers
2025-11-03 17:23:01 +01:00
nitinGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
c2d8fd495a fix: trash button centering + gap between forbidden display and trashbutton (#15571)
<img width="247" height="73" alt="CleanShot 2025-11-03 at 21 24 18"
src="https://github.com/user-attachments/assets/c0287919-be18-4dfa-96b8-5bbdeaab6693"
/>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-11-03 16:21:17 +00:00
d72aae86cb Graph margins vary depending on presence of labels (#15559)
https://github.com/user-attachments/assets/3c27fa7b-78a3-49eb-9795-53571662cf12

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-11-03 17:06:41 +01:00
06feee91f0 i18n - translations (#15570)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-03 16:47:03 +01:00
Weiko 464f80ed9b fix front lint 2025-11-03 16:38:55 +01:00
454114932a fix: ai settings page crash (#15455)
Fixes - https://github.com/twentyhq/twenty/issues/14995

---------

Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-11-03 16:36:27 +01:00
WeikoandGitHub a5e53d74dc fix calendar view when switched from other layout type bis (#15569) 2025-11-03 16:35:30 +01:00
WeikoandGitHub 0b21ac7dd8 Add permission check on calendar view drag and add new (#15556)
## Context
If selected date field of the calendar view has readonly, we should not
allow users to drag/drop cards nor allow them to add a new record
(resulting in a permission error on the BE due to the FE updating the
said field)
2025-11-03 16:33:59 +01:00
Paul RastoinandGitHub 17acfe1d2a [REQUIRED_FOR_1_10] Fix kanban foreign key migration (#15557)
# Introduction
We introduced a foreign key addition that will fail in production due to
orphan views targetting non existing fields

## Migration
The migration will be run for any new workspace successfully or any
twenty instance without corrupted data

## Upgrade command
The upgrade command will at some point allow the migration to be run
manually after removing any corrupted data

## Release note
We should remove the migration we've manually set as being run in
production
2025-11-03 15:08:35 +00:00
Charles BochetandGitHub 20576f2ee7 Add Dashboard in Lab, make Calendar available out of lab (#15560)
As per title!
2025-11-03 15:40:26 +01:00
b32ab35db9 i18n - translations (#15563)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-03 15:32:38 +01:00
WeikoandGitHub 82ac642d73 Fix calendar view when switched from other layout type not updating state (#15562)
## Context
Switching from kanban layout to calendar was not displaying records
properly. Adding the missing state update (similar to kanban case a few
lines above)
2025-11-03 15:32:23 +01:00
Raphaël BosiandGitHub 1739ee0595 Add date granularity and timezone and first day of the week to graphs (#15543)
- Allow users to choose the date granularity of the x axis and the group
by of the y axis on a bar chart
- Display those options conditionally
- Store timezones in graphs: each graph has its own timezone, defaults
to the user timezone. There will be a picker in the v2 to choose the
timezone. For now the timezone is not used by the backend, but it will
be used in filters and in group by queries.
- Store first day of the week



https://github.com/user-attachments/assets/66a5d156-dd93-4ebe-8c8f-d172f93e25be
2025-11-03 15:27:47 +01:00
MarieandGitHub 0975b06a9b [demo] Allow workspace to work with a non-system workspaceMember object (#15547)
For demo purposes, we want to work with workspaceMember has a non-system
object, allowing it to be displayed on the product, to be added custom
fields etc.
It is something we may want to do later anyway. 
This PR adds a bypassPermissionChecks on workspaceMember repository
calls. This does not provide more permissions than before for other
workspaces: workspaceMember being a system object, permissions are
already bypassed for this one. (Note that actions such inviting a new
workspaceMember, updating a workspaceMember are protected by a system
permission checked in the relevant places).

This work does **not** allow any workspace to switch their
workspaceMember object to non-system, the switch is still manual.
2025-11-03 14:57:37 +01:00
9e1c854b27 fix: updated dryrun to return correct populated record (#15484)
## Description

- This PR approaches to solve
https://github.com/twentyhq/twenty/issues/15201
- updated `createDryRunResponse` to return fully populated merged record
- this way the frontend can render the populated data it as-is without
recomputing relations
- Dry-run now uses the same nested-relations population path as the
non-dryRun flow

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2025-11-03 13:50:14 +01:00
GuillimandGitHub 120cec9885 fix migration command - workflow runs (#15540)
fix migration command to enable the id addition in the fieldmetadata
options of workflow runs

Isues was on the workfluw rin (xurrently in produciton) if we filter by
status: clicking "Stopped" also selects "Stoppping" automatically.

<img width="735" height="436" alt="Screenshot 2025-11-03 at 12 26 40"
src="https://github.com/user-attachments/assets/20fd8b71-f7be-4115-acae-9b36f53e6d5f"
/>
2025-11-03 12:38:14 +01:00
Charles BochetandGitHub 50eb8c5558 Add command to make sure v1.8 workspaces are not using FULL or PARTIAL sync stages (that should be already deprecated) (#15545)
In v1.8, we have already run a command to deprecate FULL or PARTIAL sync
stages.

However the code was fully deprecated in v1.10 and some workspaces might
still have this status used. This is to double check
2025-11-03 12:36:46 +01:00
0480ea048c i18n - translations (#15542)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-03 12:01:05 +01:00
GuillimandGitHub 4f4a13edf5 switch migrationActionsWithParent to migrationActionsWithParentTmp temporary (#15478)
The removal of views from the workspaces schema implies the deletion of 
```
view
viewFilter
viewFilterGroup
viewGroup
viewSort
```
Before it is created again in the core schema.

However, the syncmetadata that executes the pending migration fails
because it will try to
`query failed: DROP TABLE "workspace_xxxx"."view"`
before the removal of the other view related tables that contains a view
foreign key with this kind of message
> constraint FK_c5ab40cd4debb51d588752a4857 on table "viewField" depends
on table view
2025-11-03 11:50:22 +01:00
3dac899741 i18n - translations (#15541)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-03 11:48:30 +01:00
Charles BochetandGitHub 08d475b229 Revert "fix: tmp allows arbitrary temporary file / directory write via symbolic link dir parameter" (#15539)
Reverts twentyhq/twenty#15452
2025-11-03 11:42:28 +01:00
5b2950c43a Introduce SSO bypass permission. (#15417)
Closes [Core Issue
#1772](https://github.com/twentyhq/core-team-issues/issues/1772).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduces SSO bypass with a new permission flag and workspace-level
provider toggles, enabling permitted users to log in via
Google/Microsoft/Password when SSO-only, with backend enforcement and
frontend UI/hooks/queries.
> 
> - **Backend**:
> - **Permission & Enforcement**: Add `PermissionFlagType.SSO_BYPASS`;
update `AuthService` to allow login via non-SSO providers when workspace
bypass is enabled and user has `SSO_BYPASS`.
> - **Workspace Model**: Add `isGoogleAuthBypassEnabled`,
`isMicrosoftAuthBypassEnabled`, `isPasswordAuthBypassEnabled`
(migration, entity, update input, service validation).
> - **Public API**: Extend `PublicWorkspaceDataOutput` with
`authBypassProviders`; resolver computes it; permissions defaults
include `SSO_BYPASS`.
> - **Frontend**:
> - **GraphQL/State**: Generate new types/fields; add
`authBypassProviders` to `GetPublicWorkspaceDataByDomain`; new states
`workspaceAuthBypassProvidersState`, `workspaceBypassModeState`.
> - **Auth UI/Logic**: Add `useWorkspaceBypass`; update sign-in form and
footer to offer "Bypass SSO" and use merged providers when enabled;
remove auto-redirect when single SSO.
> - **Settings**: Add Security section to toggle bypass methods per
provider; conditionally show Change Password via `useCanChangePassword`.
> - **Tests/Mocks**: Update mocks and tests to include bypass
flags/providers.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8c393b2bad. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-11-03 11:40:09 +01:00
604b3e50de i18n - translations (#15531)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-03 10:36:14 +01:00
e462f191d0 fix: tmp allows arbitrary temporary file / directory write via symbolic link dir parameter (#15452)
Resolves [Dependabot Alert
255](https://github.com/twentyhq/twenty/security/dependabot/255) - fix:
tmp allows arbitrary temporary file / directory write via symbolic link
`dir` parameter.

Updated the dev-dependency `zapier-platform-cli` for it to depend on tmp
0.2.4 and also ran `yarn up tmp --recursive` to update the version of
tmp elsewhere.

Not expecting any breaking changes to twenty-zapier since
`zapier-platform-cli` is marked as a development dependency.

Co-authored-by: martmull <martmull@hotmail.fr>
2025-11-03 10:17:08 +01:00
Félix MalfaitandGitHub 7c854ba816 Remove Hacktoberfest from README (#15530)
As per title
2025-11-03 10:03:03 +01:00
neo773andGitHub f9eb06f015 fix IMAP onboarding (#15444) 2025-11-02 13:33:03 +01:00
GuillimandGitHub 53bb534af8 MORPH for relationDecorator (#15420)
# Adding MORPH support  to the relationDecorator

Extends the @WorkspaceRelation decorator to support morph relations by
adding isMorphRelation and morphId options

The implementation enforces type safety through TypeScript discriminated
unions, ensuring morphId is required when isMorphRelation: true, and
includes runtime validation that throws a descriptive error if morphId
is missing.

The morph relation metadata is properly stored in metadataArgsStorage
and integrates seamlessly with the existing StandardFieldRelationFactory
to convert decorated fields into FieldMetadataType.MORPH_RELATION
entities with appropriate database constraints.



To test :
in person entity, add
```ts
  @WorkspaceRelation({
    standardId: PERSON_STANDARD_FIELD_IDS.testRelatedRecordCompany,
    type: RelationType.MANY_TO_ONE,
    label: msg`Test Related Record of Company`,
    description: msg`Test relation to company`,
    icon: 'IconLink',
    inverseSideTarget: () => CompanyWorkspaceEntity,
    inverseSideFieldKey: 'testRelatedPeople',
    onDelete: RelationOnDeleteAction.CASCADE,
    isMorphRelation: true,
    morphId: PERSON_STANDARD_FIELD_IDS.testRelatedRecordMorphId,
  })
  @WorkspaceIsNullable()
  @WorkspaceIsSystem()
  testRelatedRecordCompany: Relation<CompanyWorkspaceEntity> | null;

  @WorkspaceJoinColumn('testRelatedRecordCompany')
  testRelatedRecordCompanyId: string | null;

  @WorkspaceRelation({
    standardId: PERSON_STANDARD_FIELD_IDS.testRelatedRecordOpportunity,
    type: RelationType.MANY_TO_ONE,
    label: msg`Test Related Record of Opportunity`,
    description: msg`Test relation to opportunity`,
    icon: 'IconLink',
    inverseSideTarget: () => OpportunityWorkspaceEntity,
    inverseSideFieldKey: 'testRelatedPeople',
    onDelete: RelationOnDeleteAction.CASCADE,
    isMorphRelation: true,
    morphId: PERSON_STANDARD_FIELD_IDS.testRelatedRecordMorphId,
  })
  @WorkspaceIsNullable()
  @WorkspaceIsSystem()
  testRelatedRecordOpportunity: Relation<OpportunityWorkspaceEntity> | null;

  @WorkspaceJoinColumn('testRelatedRecordOpportunity')
  testRelatedRecordOpportunityId: string | null;
```

in opportunity,
```ts
@WorkspaceRelation({
    standardId: OPPORTUNITY_STANDARD_FIELD_IDS.testRelatedPeople,
    type: RelationType.ONE_TO_MANY,
    label: msg`Test Related People`,
    description: msg`People linked to the opportunity via Test Related Record`,
    icon: 'IconUsers',
    inverseSideTarget: () => PersonWorkspaceEntity,
    inverseSideFieldKey: 'testRelatedRecordOpportunity',
    onDelete: RelationOnDeleteAction.SET_NULL,
  })
  @WorkspaceIsNullable()
  @WorkspaceIsSystem()
  testRelatedPeople: Relation<PersonWorkspaceEntity[]>;
  ```

in company,
```ts
  @WorkspaceRelation({
    standardId: COMPANY_STANDARD_FIELD_IDS.testRelatedPeople,
    type: RelationType.ONE_TO_MANY,
    label: msg`Test Related People`,
description: msg`People linked to the company via Test Related Record`,
    icon: 'IconUsers',
    inverseSideTarget: () => PersonWorkspaceEntity,
    inverseSideFieldKey: 'testRelatedRecordCompany',
    onDelete: RelationOnDeleteAction.SET_NULL,
  })
  @WorkspaceIsNullable()
  @WorkspaceIsSystem()
  testRelatedPeople: Relation<PersonWorkspaceEntity[]>;
```

In constants/standard-field-ids.ts, add the standard fields ids
```ts
// COMPANY_STANDARD_FIELD_IDS
testRelatedPeople: '20202020-7a90-47e9-b31f-916a716fd212',

// OPPORTUNITY_STANDARD_FIELD_IDS
testRelatedPeople: '20202020-7a90-47e9-b31f-916a716fd213',

// PERSON_STANDARD_FIELD_IDS
testRelatedRecordOpportunity: '20202020-5a90-47e9-b31f-916a716fd211',
testRelatedRecordCompany: '20202020-1eb2-4298-910b-66b015b36d72',
testRelatedRecordMorphId: '20202020-6ccf-48e3-bb92-bc9961bc011e',
```
2025-11-02 13:31:48 +01:00
Charles BochetandGitHub 498d89633c Fix view favorite making the app crash (#15517)
On new workspaces, as they come without the "view" object which not part
of engine metadata, favorites pointing to views make the app crashes.

This fixes it
2025-11-01 20:05:17 +01:00
neo773andGitHub 44c0b9f94b refactor messaging error handling (#15416) 2025-11-01 20:03:41 +01:00
c42c2590de i18n - translations (#15516)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-01 18:45:55 +01:00
afeb505eed [Breaking Change] Implement reliable date picker utils to handle all timezone combinations (#15377)
This PR implements the necessary tools to have `react-datepicker`
calendar and our date picker components work reliably no matter the
timezone difference between the user execution environment and the user
application timezone.

Fixes https://github.com/twentyhq/core-team-issues/issues/1781

This PR won't cover everything needed to have Twenty handle timezone
properly, here is the follow-up issue :
https://github.com/twentyhq/core-team-issues/issues/1807

# Features in this PR

This PR brings a lot of features that have to be merged together.

- DATE field type is now handled as string only, because it shouldn't
involve timezone nor the JS Date object at all, since it is a day like a
birthday date, and not an absolute point in time.
- DATE_TIME field wasn't properly handled when the user settings
timezone was different from the system one
- A timezone abbreviation suffix has been added to most DATE_TIME
display component, only when the timezone is different from the system
one in the settings.
- A lot of bugs, small features and improvements have been made here :
https://github.com/twentyhq/core-team-issues/issues/1781

# Handling of timezones

## Essential concepts

This topic is so complex and easy to misunderstand that it is necessary
to define the precise terms and concepts first. It resembles character
encoding and should be treated with the same care.

- Wall-clock time : the time expressed in the timezone of a user, it is
distinct from the absolute point in time it points to, much like a
pointer being a different value than the value that it points to.
- Absolute time : a point in time, regardless of the timezone, it is an
objective point in time, of course it has to be expressed in a given
timezone, because we have to talk about when it is located in time
between humans, but it is in fact distinct from any wall clock time, it
exists in itself without any clock running on earth. However, by
convention the low-level way to store an absolute point in time is in
UTC, which is a timezone, because there is no way to store an absolute
point in time without a referential, much like a point in space cannot
be stored without a referential.
- DST : Daylight Save Time, makes the timezone shift in a specific
period every year in a given timezone, to make better use of longer days
for various reasons, not all timezones have DST. DST can be 1 hour or 30
min, 45 min, which makes computation difficult.
- UTC : It is NOT an “absolute timezone”, it is the wall-clock time at
0° longitude without DST, which is an arbitrary and shared human
convention. UTC is often used as the standard reference wall-clock time
for talking about absolute point in time without having to do timezone
and DST arithmetic. PostgreSQL stores everything in UTC by convention,
but outputs everything in the server’s SESSION TIMEZONE.

## How should an absolute point in time be stored ?

Since an absolute point in time is essentially distinct from its
timezone it could be stored in an absolute way, but in practice it is
impossible to store an absolute point in time without a referential. We
have to say that a rocket launched at X given time, in UTC, EST, CET,
etc. And of course, someone in China will say that it launched at 10:30,
while in San Francisco it will have launched at 19:30, but it is THE
SAME absolute point in time.

Let’s take a related example in computer science with character
encoding. If a text is stored without the associated encoding table, the
correct meaning associated to the bits stored in memory can be lost
forever. It can become impossible for a program to guess what encoding
table should be used for a given text stored as bits, thus the glitches
that appeared a lot back in the early days of internet and document
processing.

The same can happen with date time storing, if we don’t have the
timezone associated with the absolute point in time, the information of
when it absolutely happened is lost.

It is NOT necessary to store an absolute point in time in UTC, it is
more of a standard and practical wall-clock time to be associated with
an absolute point in time. But an absolute point in time MUST be store
with a timezone, with its time referential, otherwise the information of
when it absolutely happened is lost.

For example, it is easier to pass around a date as a string in UTC, like
`2024-01-02T00:00:00Z` because it allows front-end and back-end code to
“talk” in the same standard and DST-free wall-clock time, BUT it is not
necessary. Because we have date libraries that operate on the standard
ISO timezone tables, we can talk in different timezone and let the
libraries handle the conversion internally.

It is false to say that UTC is an absolute timezone or an absolute point
in time, it is just the standard, conventional time referential, because
one can perfectly store every absolute points in time in UTC+10 with a
complex DST table and have the exactly correct absolute points in time,
without any loss of information, without having any UTC+0 dates
involved.

Thus storing an absolute point in time without a timezone associated,
for example with `timestamp` PostgreSQL data type, is equivalent to
storing a wall-clock time and then throwing away voluntarily the
information that allows to know when it absolutely happened, which is a
voluntary data-loss if the code that stores and retrieves those
wall-clock points in time don’t store the associated timezone somewhere.

This is why we use `timestamptz` type in PostgreSQL, so that we make
sure that the correct absolute point in time is stored at the exact time
we send it to PostgreSQL server, no matter the front-end, back-end and
SQL server's timezone differences.

## The JavaScript Date object

The native JavaScript Date object is now officially considered legacy
([source](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)),
the Date object stores an absolute point in time BUT it forces the
storage to use its execution environment timezone, and one CANNOT modify
this timezone, this is a legacy behavior.

To obtain the desired result and store an absolute point in time with an
arbitrary timezone there are several options :

- The new Temporal API that is the successor of the legacy Date object.
- Moment / Luxon / @date-fns/tz that expose objects that allow to use
any timezone to store an absolute point in time.

## How PostgreSQL stores absolute point in times

PostgreSQL stores absolute points in time internally in UTC
([source](https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-DATETIME-INPUT-TIME-STAMPS)),
but the output date is expressed in the server’s session timezone
([source](https://www.postgresql.org/docs/current/sql-set.html)) which
can be different from UTC.

Example with the object companies in Twenty seed database, on a local
instance, with a new “datetime” custom column :

<img width="374" height="554" alt="image"
src="https://github.com/user-attachments/assets/4394cb43-d97e-4479-801d-ca068f800e39"
/>

<img width="516" height="524" alt="image"
src="https://github.com/user-attachments/assets/b652f36a-d2e2-47a4-8950-647ca688cbbd"
/>

## Why can’t I just use the JavaScript native Date object with some
manual logic ?

Because the JavaScript Date object does not allow to change its internal
timezone, the libraries that are based on it will behave on the
execution environment timezone, thus leading to bugs that appear only on
the computers of users in a timezone but not for other in another
timezone.

In our case the `react-datepicker` library forces to use the `Date`
object, thus forcing the calendar to behave in the execution environment
system timezone, which causes a lot of problems when we decide to
display the Twenty application DATE_TIME values in another timezone than
the user system one, the bugs that appear will be of the off-by-one date
class, for example clicking on 23 will select 24, thus creating an
unreliable feature for some system / application timezone combinations.

A solution could be to manually compute the difference of minutes
between the application user and the system timezones, but that’s not
reliable because of DST which makes this computation unreliable when DST
are applied at different period of the year for the two timezones.

## Why can’t I compute the timezone difference manually ?

Because of DST, the work to compute the timezone difference reliably,
not just for the usual happy path, is equivalent to developing the
internal mechanism of a date timezone library, which is equivalent to
use a library that handles timezones.

## Using `@date-fns/tz` to solve this problem

We could have used `luxon` but it has a heavy bundle size, so instead we
rely here on `@date-fns/tz` (~1kB) which gives us a `TZDate` object that
allows to use any given timezone to store an absolute point-in-time.

The solution here is to trick `react-datepicker` by shifting a Date
object by the difference of timezone between the user application
timezone and the system timezone.

Let’s take a concerte example.

System timezone : Midway,  ⇒ UTC-11:00, has no DST.

User application timezone : Auckland, NZ ⇒ UTC+13:00, has a DST.

We’ll take the NZ daylight time, so that will make a timezone difference
of 24 hours !

Let’s take an error-prone date : `2025-01-01T00:00:00` . This date is
usually a good test-case because it can generate three classes of bugs :
off-by-one day bugs, off-by-one month bugs and off-by-one year bugs, at
the same time.

Here is the absolute point in time we take expressed in the different
wall-clock time points we manipulate


Case | In system timezone ⇒ UTC-11 | In UTC | In user application
timezone ⇒ UTC+13
-- | -- | -- | --
Original date | `2024-12-31T00:00:00-11:00` | `2024-12-31T11:00:00Z` |
`2025-01-01T00:00:00+13:00`
Date shifted for react-datepicker | `2025-01-01T00:00:00-11:00` |
`2025-01-01T11:00:00Z` | `2025-01-02T00:00:00+13:00`

We can see with this table that we have the number part of the date that
is the same (`2025-01-01T00:00:00`) but with a different timezone to
“trick” `react-datepicker` and have it display the correct day in its
calendar.

You can find the code in the hooks
`useTurnPointInTimeIntoReactDatePickerShiftedDate` and
`useTurnReactDatePickerShiftedDateBackIntoPointInTime` that contain the
logic that produces the above table internally.

## Miscellaneous

Removed FormDateFieldInput and FormDateTimeFieldInput stories as they do
not behave the same depending of the execution environment and it would
be easier to put them back after having refactored FormDateFieldInput
and FormDateTimeFieldInput

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-01 18:31:24 +01:00
EtienneandGitHub 3a203040f7 Fix - Multiple banners issue (#15506)
Done : 
- Fix multiple banners issue
- Lift impersonation banner


After 
<img width="800" height="400" alt="Screenshot 2025-10-31 at 18 05 02"
src="https://github.com/user-attachments/assets/7d5949d4-1c8b-4a4f-91c1-c115e53436fb"
/>
2025-10-31 19:17:31 +01:00
Baptiste DevessierandGitHub 5f0d24798a Support workflows in record page layouts (#15471)
https://github.com/user-attachments/assets/275a02a3-7054-45d1-9423-75bb5223a8ba
2025-10-31 18:45:58 +01:00
WeikoandGitHub 09c704c8bd Add useGroupBy hook + update calendar view to use groupBy (#15439)
## Context
Took inspiration from findMany + kanban => Implemented a hook for the
new groupBy API endpoints
Fixed an issue when DnD to an empty day
2025-10-31 18:39:22 +01:00
Raphaël BosiandGitHub bb471cb8a5 Bar chart: Prevent left tick labels to overlap on label (#15499)
Prevent left tick labels to overlap on label by truncating the tick
label
2025-10-31 22:50:22 +05:30
cd4a151a21 i18n - translations (#15504)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-31 17:47:12 +01:00
Thomas TrompetteandGitHub 71e7063fc4 Move http node to backend (#15424)
Fixes https://github.com/twentyhq/twenty/issues/14491

Also adding an url validator.
2025-10-31 17:46:58 +01:00
Abdul RahmanandGitHub 9f97be67b1 Migrate documentation to Mintlify and configure 301 redirects (#15502)
## Summary
Completes the migration of all documentation from twenty-website to a
new Mintlify-powered documentation site at docs.twenty.com.

## Changes Made

### New Package: `twenty-docs`
-  Created new Mintlify documentation package
-  Migrated 95 content pages (user-guide, developers, twenty-ui)
-  Migrated 81 images
-  Converted all custom components to Mintlify native components
-  Configured navigation with 2 tabs and 94 pages
-  Added Helper AI Agent with searchArticles tool for docs search

### Updated: `twenty-website`
-  Added 11 redirect rules (301 permanent) in next.config.js
-  Removed all documentation content (111 files)
-  Removed documentation routes (user-guide, developers, twenty-ui)
-  Removed documentation components (9 files)
-  Updated keystatic.config.ts
-  Preserved all marketing/release pages

### Updated: Core Files
-  Updated README.md - docs links point to docs.twenty.com
-  Updated CONTRIBUTING.md - code quality link updated
-  Updated SupportDropdown.tsx - user guide link updated
-  Updated Footer.tsx - user guide link updated
2025-10-31 17:44:14 +01:00
Thomas TrompetteandGitHub 5f13e6fcf4 Put delete button on step footer + add unique fields on upsert action (#15497)
<img width="491" height="823" alt="Capture d’écran 2025-10-31 à 14 54
38"
src="https://github.com/user-attachments/assets/8058a6a3-8a6c-4cdd-93d9-2af71208dc5a"
/>
2025-10-31 16:39:45 +00:00
Paul RastoinandGitHub d640b93096 Improve v2 and cache invalidation perfs (#15467)
# Introduction
Log are debug logs of
`packages/twenty-server/test/integration/metadata/suites/object-metadata/create-delete-and-create-object-metadata-v2.integration-spec.ts`run
ten times in a row on clean db reset

## Next
Will improve cache computation to lighter invalidation.
RelationLoad `query` does not seem to work with typeorm so I'll continue
the custom integration i've started in
https://github.com/twentyhq/twenty/tree/optimize-cache-read-v2

## Integration tests duration
Significant test duration improvement too
### Before
<img width="2632" height="1402" alt="image"
src="https://github.com/user-attachments/assets/2f1f0ccf-44de-4856-bfe1-4f45a351763a"
/>

### After
<img width="2632" height="1402" alt="image"
src="https://github.com/user-attachments/assets/4bc9e6db-3046-48b9-b903-1464053936c4"
/>


## What's next
- The legacy cache invalidation removal
- Factorizing redis calls in only one operation

## Autogenerated performance comparison ( including mutation refactor
too )

[Before](https://gist.github.com/prastoin/3c1e21fa9e3b3ce4b0716902ff4a2dd6)

[After](https://gist.github.com/prastoin/7bfddd14bfded2e4991a9378970a026d)

The optimized implementation shows **dramatic performance improvements**
across all metrics:

- 🚀 **Cache Invalidation**: 156.3ms → 76.8ms (**50.9% faster**)
- 🚀 **Builder Operations**: 21.3ms → 14.2ms (**33.3% faster**)
-  **Consistency**: 16.4% more predictable performance

---

## 1. Overall Performance Summary

| Component | Before (avg) | After (avg) | Best (After) | Worst (After)
| Improvement |

|-----------|-------------|-------------|--------------|---------------|-------------|
| **Total Execution Time** | 180.2ms | 110.5ms | 52.3ms | 585.9ms |
**38.7% faster**  |
| **Cache Invalidation** | 156.3ms | 76.8ms | 47.8ms | 285.1ms | **50.9%
faster**  |
| **Transaction Execution** | 22.4ms | 22.1ms | 0.99ms | 314.2ms |
Similar |
| **Initial Cache Retrieval** | 0.81ms | 2.08ms | 0.21ms | 8.24ms |
Similar |
| **Entity Builder (total)** | 21.3ms | 14.2ms | 0.36ms | 42.5ms |
**33.3% faster**  |

### Total Execution Time Distribution

#### Before (Legacy Sequential)
```
Time (ms)    Count  Percentage  Visualization
< 150         18      16%       ████
150-180       32      29%       ███████
180-210       35      32%       ████████
210-250       17      15%       ████
250-350        6       5%       █
> 350          2       2%       ▌
```

#### After (Optimized Parallel)
```
Time (ms)    Count  Percentage  Visualization
< 70          28      31%       ████████
70-100        31      34%       █████████
100-150       18      20%       █████
150-200        8       9%       ██
200-300        4       4%       █
> 300          2       2%       ▌
```
---

## 2. Builder Performance Breakdown

### Field Metadata Builder

| Operation | Before (avg) | After (avg) | Improvement |
|-----------|-------------|-------------|-------------|
| Matrix computation | 3.5ms | 3.4ms | Similar |
| Creation validation | 15.2ms | 2.1ms | **86% faster**  |
| Deletion validation | 0.08ms | 0.06ms | Similar |
| Update validation | 1.3ms | 0.09ms | **93% faster**  |
| Entity processing | 18.6ms | 11.8ms | **37% faster**  |
| **Total validateAndBuild** | **21.3ms** | **14.2ms** | **33% faster**
 |

#### Performance Distribution
```
Before:  ▁▂▄█████▆▄▂▁     (wide spread, 15-28ms range)
After:   ▁▁▃█████▃▁▁       (tight clustering, 10-18ms range)
```

## 4. Cache Invalidation Performance Breakdown

### Cache Invalidation Summary

| Metric | Before (Legacy) | After (Optimized) | Improvement |
|--------|-----------------|-------------------|-------------|
| **Best Time** | 131.965ms | 47.833ms | **63.7% faster**  |
| **10th Percentile** | 140.2ms | 51.7ms | **63.1% faster**  |
| **25th Percentile** | 146.1ms | 54.4ms | **62.7% faster**  |
| **Median (50th)** | 155.1ms | 63.4ms | **59.1% faster**  |
| **Average** | 156.3ms | 76.8ms | **50.9% faster**  |
| **75th Percentile** | 160.2ms | 90.2ms | **43.7% faster**  |
| **90th Percentile** | 191.7ms | 100.2ms | **47.7% faster**  |
| **95th Percentile** | 235.6ms | 110.3ms | **53.2% faster**  |
| **99th Percentile** | 278.2ms | 224.9ms | **19.1% faster**  |
| **Worst Time** | 383.914ms | 285.102ms | **25.7% faster**  |

### Cache Invalidation Time Distribution

#### Before (Legacy Sequential)
```
Time (ms)    Count  Percentage  Visualization
130-140       3       3%        ▊
140-150      15      14%        ████
150-160      48      44%        ███████████
160-180      31      28%        ███████
180-220       8       7%        ██
220-280       3       3%        ▊
> 280         2       2%        ▌
```

#### After (Optimized Parallel + Intersection)
```
Time (ms)    Count  Percentage  Visualization
< 50          3       3%        ▊
50-60        27      25%        ███████
60-70        25      23%        ██████
70-90        25      23%        ██████
90-100       15      14%        ████
100-120       8       7%        ██
120-150       3       3%        ▊
> 150         4       4%        █
```

## 6. Performance Consistency Analysis

### Standard Deviation & Variance

| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| **Cache Invalidation Std Dev** | 42.1ms | 35.2ms | **16.4% more
consistent**  |
| **Total Execution Std Dev** | 68.3ms | 89.1ms | Slightly more variable
|
| **Coefficient of Variation (Cache)** | 26.9% | 45.8% | More variance |
| **Outliers (> 2σ)** | 5 cases | 3 cases | **40% fewer outliers**  |

---
2025-10-31 16:20:51 +00:00
Raphaël BosiandGitHub 2d1a89c4c2 Update minimum chart sizes (#15500)
Update minimum chart sizes
2025-10-31 21:29:04 +05:30
MarieandGitHub bcdc07273e Fix orderBy, groupBy, and orderByForRecords on foreignKey (#15480)
For the variables orderBy (for findMany and groupBy), groupBy (for
groupBy) and orderByForRecords (for groupBy), we were wrongfully adding
the foreign key field (eg: pointOfContact) by its joinColumnName (eg:
pointOfContactId) as the variable key (eg. `orderBy: { pointOfContactId:
"AscNullsFirst" } }`. That broke because then this key is used to
identify the field in the parsers.

This went unnoticed because this order / group option is not very
interesting as it is limited to the id for now, but it s still better to
have it work than crash!

before (on findMany)
<img width="1841" height="674" alt="flawn_order_by_pocId"
src="https://github.com/user-attachments/assets/3ccd7604-041d-4b7e-8b6a-c1d268440a45"
/>

after (on findMany)
<img width="1182" height="805" alt="image"
src="https://github.com/user-attachments/assets/e9253683-bcbe-429e-bbef-e334c7cc76af"
/>
2025-10-31 15:13:49 +01:00
Abdullah.andGitHub 4224a46854 fix: regular expression denial of service (ReDoS) in cross-spawn (#15495)
Resolves [Dependabot Alert
#161](https://github.com/twentyhq/twenty/security/dependabot/161) -
regular expression denial of service (ReDoS) in cross-spawn.

Ran `yarn up cross-spawn --recursive` to move the version of cross-spawn
used from 7.0.3 to 7.0.6.
2025-10-31 15:06:31 +01:00
nitinandGitHub 809791a4a8 fix: Orderby secondary dimension sum (#15493)
before:


https://github.com/user-attachments/assets/6919c45b-1435-408f-87e3-0452dd70fbdb

after:


https://github.com/user-attachments/assets/efa60d28-ac04-4219-831a-92aada13fa9c
2025-10-31 13:54:13 +01:00
3d21ffb4d1 i18n - translations (#15494)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-31 13:01:39 +01:00
Raphaël BosiandGitHub cf382ccdd9 Fix maximum number of bars for stacked bars (#15481)
The maximum number of bars feature has been implemented before the
stacked bar one, so it didn't support it.
Now, the same number of bars is displayed with and without group by when
we are in stacked mode.
2025-10-31 17:25:47 +05:30
nitinandGitHub 1b02bc7cc4 remove values/formatted values from chart legends (#15490)
before:

<img width="639" height="385" alt="Screenshot 2025-10-31 at 15 29 01"
src="https://github.com/user-attachments/assets/5769a160-205d-4a03-ab7b-e037c65dd743"
/>


after:

<img width="667" height="371" alt="Screenshot 2025-10-31 at 15 27 51"
src="https://github.com/user-attachments/assets/12a4e034-6262-43a9-b257-894d74462d73"
/>
2025-10-31 17:18:55 +05:30
Ranjeet BaraikandGitHub 6ed1fd841d fix: composite field label retrieval in spreadsheet import utility (#15489)
Fixes - https://github.com/twentyhq/twenty/issues/15368

Seems like the sub field was not being used for the actual label lookup
part

<img width="1302" height="354" alt="image"
src="https://github.com/user-attachments/assets/444f76be-117b-4b8b-91fe-dedd293e09af"
/>
2025-10-31 11:39:39 +01:00
nitinandGitHub d6bfbcc5ab add max widths on bars (#15487)
closes
https://discord.com/channels/1130383047699738754/1433444230176440560
before:


https://github.com/user-attachments/assets/db93c705-7c0a-407b-99d8-ecf8fd9eac1b


after:


https://github.com/user-attachments/assets/cb2a5e74-ea41-4381-9fbc-04efee12a50e
2025-10-31 11:15:53 +01:00
Abdul RahmanandGitHub 2c39fc04c2 feat: Migrate documentation to Mintlify and implement Helper Agent with search functionality (#15443) 2025-10-31 10:17:54 +01:00
nitinandGitHub 5211d6ac7e fix: make $groupBy parameter required in group-by queries (#15485)
before:

<img width="953" height="692" alt="Screenshot 2025-10-31 at 12 16 22"
src="https://github.com/user-attachments/assets/d2ec2a49-256d-4f17-baa7-6fb541e6e691"
/>

after:

<img width="960" height="718" alt="Screenshot 2025-10-31 at 12 16 34"
src="https://github.com/user-attachments/assets/39843363-8f77-40cc-8203-ed9895efa57e"
/>
2025-10-31 14:10:01 +05:30
769ce95cde Data labels improvements (#15475)
Create custom total component and display the total instead of each
group separately



https://github.com/user-attachments/assets/4e3edde8-9675-4bb1-834a-98dbff016063



https://github.com/user-attachments/assets/294555cc-a64b-4148-b1b9-f1dc0f0322ae

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-10-30 23:47:37 +05:30
nitinandGitHub 4c35cf305f Add support for negative bars on bar chart (#15418)
in app:

<img width="580" height="591" alt="Screenshot 2025-10-29 at 01 47 51"
src="https://github.com/user-attachments/assets/9e16a597-6367-454d-a726-668beac90e04"
/>

<img width="747" height="582" alt="Screenshot 2025-10-29 at 02 30 15"
src="https://github.com/user-attachments/assets/d06eb443-16ac-4394-bf4f-e6063f1ac12f"
/>

new stories: 

<img width="569" height="359" alt="Screenshot 2025-10-29 at 01 46 50"
src="https://github.com/user-attachments/assets/a4cd33e2-3f15-4b8d-8849-c2d990246dec"
/>
<img width="564" height="360" alt="Screenshot 2025-10-29 at 01 46 45"
src="https://github.com/user-attachments/assets/014a2110-53e4-4f99-afda-1d8c5412a815"
/>
<img width="604" height="372" alt="Screenshot 2025-10-29 at 01 46 40"
src="https://github.com/user-attachments/assets/bf7a73b4-fe29-40b7-b1a0-2894d5cbeccf"
/>
<img width="635" height="395" alt="Screenshot 2025-10-29 at 01 46 34"
src="https://github.com/user-attachments/assets/3cdfd3b9-dc76-4cf2-98e5-8e2a74e02ac6"
/>
<img width="652" height="408" alt="Screenshot 2025-10-29 at 01 46 30"
src="https://github.com/user-attachments/assets/c2837d8d-371f-44ac-b66b-8f41ba69245e"
/>
2025-10-30 17:40:34 +01:00
0cbd1e8ec5 fix: login redirection to active objects (#15366)
Fixes - https://github.com/twentyhq/twenty/issues/15364

- Removed `activeNonSystemObjectMetadataItems` from the hook as it was
not necessary. Hook use `alphaSortedActiveNonSystemObjectMetadataItems`
now.
- Correctly check for read permissions.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-30 17:31:26 +01:00
Baptiste DevessierandGitHub 51fdaf2731 Some fixes for colors (#15479)
Please note the background colors of the tags and of the nodes

## Before

<img width="3456" height="2161" alt="CleanShot 2025-10-30 at 16 03
21@2x"
src="https://github.com/user-attachments/assets/09cbd1bd-26e2-4e05-88bc-f7d96de8a004"
/>

## After

<img width="3456" height="2160" alt="CleanShot 2025-10-30 at 17 03
25@2x"
src="https://github.com/user-attachments/assets/dc4fe113-1489-4476-a8b6-4cb446addcd5"
/>
2025-10-30 16:23:22 +00:00
Paul RastoinandGitHub a16fcebe67 Activate v2 for new workspaces (#15472) 2025-10-30 17:14:14 +01:00
428822f52d i18n - translations (#15477)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-30 16:35:23 +01:00
ab0cb67686 Render depends on menu items conditionally in chart settings + fix min max values (#15391)
closes
https://discord.com/channels/1130383047699738754/1430894689317294152

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-10-30 20:56:37 +05:30
nitinandGitHub 2510cbf614 Add lock on dashboard restricted charts (#15476)
closes
https://discord.com/channels/1130383047699738754/1433452994132840478
2025-10-30 14:59:34 +00:00
nitinandGitHub 33eaa4f2a2 Fix bar chart X-axis labels when groupBy matches aggregate field (#15473)
closes -
https://discord.com/channels/1130383047699738754/1430899754728030309
2025-10-30 15:53:17 +01:00
nitinandGitHub abcc891aed overflown tabs should be selected upon clicking edit right button (#15469)
as per title
2025-10-30 19:23:00 +05:30
26039d491f i18n - translations (#15468)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-30 14:38:52 +01:00
nitinandGitHub 28333815d5 update chart tooltip designs (#15426)
closes
https://discord.com/channels/1130383047699738754/1430845815634657320

~~TODO: add truncation~~
2025-10-30 19:07:59 +05:30
EtienneandGitHub 2461296158 Common - fixes (#15463)
Fixes https://github.com/twentyhq/twenty/issues/15435
Fixes https://github.com/twentyhq/private-issues/issues/338
Fixes https://github.com/twentyhq/twenty/issues/15457
2025-10-30 14:29:57 +01:00
d6d9ebf6eb i18n - translations (#15466)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-30 14:23:40 +01:00
nitinandGitHub 369b1b19af Tabs sidepanel settings on dashboards (#15454)
question -- should we have confirmation modal on delete -- if yes --
should it appear on save -- or on delete?
figma -
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=79469-817497&t=5gFTRiI5f8nPyzc6-0
Note - Figma has a new side panel header, which is unavailable for now,
so I used the existing one

In a follow-up, we could even have icons for tabs -- would be cool --
and an icon picker for the icons?

followups which could be addressed in separate PRs - 
- ~~tabs being edited state (select state?) -- this would have blue
border around tab~~ done
- add icons on tabs -- need to update the entity to add icon -- and set
a default (dashboard) -- at least
- icon picker in the sidepanel header

closes -
https://discord.com/channels/1130383047699738754/1430204556884836532

video QA





https://github.com/user-attachments/assets/a4ad4b93-911d-46ce-9b68-347fd48fe933
2025-10-30 18:45:31 +05:30
Abdullah.andGitHub f367bd6072 fix: vite related dependabot alerts (#15464)
Resolves [14 Dependabot
Alerts](https://github.com/twentyhq/twenty/security/dependabot?q=is%3Aopen+package%3Avite+manifest%3Ayarn.lock+has%3Apatch)
simultaneously.

Vitest 1.4.0 was imported in root package.json, which further imported
Vite 5. However, Vitest solved no purpose at the moment since we still
rely on Jest for testing. Therefore, removed the package and we can
import the latest 4x version when we move from Jest to Vitest.

For the rest of the use-cases of Vite, ran `yarn up vite --recursive`
for the version used to be greater than 7.0.8.

<p align="center">
<img width="403" height="132" alt="image"
src="https://github.com/user-attachments/assets/a4ff7a75-2e3f-4dea-9f40-9cfdf07d6252"
/>
</p>
2025-10-30 14:00:28 +01:00
Charles BochetandGitHub eba3b0ca88 Simplify Code on FetchMore (#15465)
Simplifying a bit more fetchMore / lazyQuery api
2025-10-30 13:36:30 +01:00
Thomas TrompetteandGitHub a82b74c1ff Make upsert action body common with create record instead of update record (#15442)
We do not want the fields to update multiselect for upsert record
action. We want all available fields displayed by default.
This makes upsert record action closer to create record than update
record.

This PR: 
- deletes WorkflowUpdateRecordBody that was common between update and
upsert and put back content into update
- creates WorkflowCreateRecordBody that is now common between create and
upsert
- simplifies shouldDisplayFormField

Before - using fields to update as update record action
<img width="546" height="823" alt="Capture d’écran 2025-10-30 à 10 00
24"
src="https://github.com/user-attachments/assets/9206bc8b-75c2-40fa-a8de-e708b6b2cd05"
/>

After - displaying all fields as create record action
<img width="546" height="823" alt="Capture d’écran 2025-10-30 à 10 00
04"
src="https://github.com/user-attachments/assets/87141a47-946f-4604-be55-f4c21ff4a3d8"
/>
2025-10-30 13:36:16 +01:00
martmullandGitHub 8edb2c5520 Stop using .env variables to authenticate with cli (#15461)
- as title, solves our user facing authentication issues using the
twenty-cli
- update twenty-cli version (breaking change from previous PR)
2025-10-30 11:18:25 +00:00
65a329e900 Fix grip size on widgets (#15460)
Fix grip size on widgets

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-10-30 11:38:02 +01:00
1929605fd9 fix: password reset redirection (#15421)
Fixes - https://github.com/twentyhq/twenty/issues/15131

Replace navigate with redirect in PasswordReset component to prevent
race conditions

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
2025-10-30 10:24:06 +00:00
MarieandGitHub 1ad8c05fbc groupBy fix + typeMapper fix (#15433)
groupBy fix: when a group's dimension value is NULL, we need to adapt
the raw sql (stage: NULL -> stage IS NULL)

typeMapper fix: a graphql type should be made non-nullable if was
indicated so + does not have a default value. our check on not having a
default value was limited to having a null defaultValue instead of
having a null or undefined defaultValue. This is a breaking change, but
all the queries that were providing a null value for these args were not
functioning anyway, and luckily in the FE we declared all queries adding
a `!` already.
2025-10-30 10:14:56 +00:00
Raphaël BosiandGitHub 19ea9fff97 Set default graph axis display to NONE (#15459)
Set default graph axis display to NONE
2025-10-30 10:14:25 +00:00
WeikoandGitHub 736fac021d Add contextMenu actions to calendar view (#15451)
<img width="432" height="307" alt="Screenshot 2025-10-29 at 19 31 38"
src="https://github.com/user-attachments/assets/61965305-3a20-46de-b47f-7ac78cb1228c"
/>
2025-10-30 10:59:11 +01:00
Abdullah.andGitHub 3401216cc8 fix: validator.js has a URL validation bypass vulnerability in its isURL function. (#15437)
Resolves [Dependabot Alert
299](https://github.com/twentyhq/twenty/security/dependabot/299) -
validator has a URL validation bypass vulnerability in its isURL
function.

Used `yarn up validator --recursive` to update the version in yarn.lock
file.
2025-10-29 20:34:59 +01:00
Abdullah.andGitHub 9a0ce141d4 chore: next.js may leak x-middleware-subrequest-id to external hosts. (#15438)
Resolves [Dependabot Alert
298](https://github.com/twentyhq/twenty/security/dependabot/298) -
next.js may leak x-middleware-subrequest-id to external hosts.

Updated the version of react-email used to update the version of
Next.js.
2025-10-29 20:34:14 +01:00
Abdullah.andGitHub f2d9262e6a fix: on-headers is vulnerable to http response header manipulation (#15453)
Resolves [Dependabot Alert
245](https://github.com/twentyhq/twenty/security/dependabot/245) -
on-headers is vulnerable to http response header manipulation.

Updated the version of express-session from `1.18.1` to `1.18.2`.
2025-10-29 20:32:15 +01:00
Raphaël BosiandGitHub 198bf5a333 Complete color refactoring (#15414)
# Complete color refactoring

Closes https://github.com/twentyhq/core-team-issues/issues/1779

- Updated all colors to use Radix colors with P3 color space allowing
for brighter colors
- Created our own gray scale interpolated on Radix's scale to have the
same values for grays as the old ones in the app
- Introduced dark and light colors as well as there transparent versions
- Added many new colors from radix that can be used in the tags or in
the graphs
- Updated multiple color utilities to match new behaviors
- Changed the computation of Avatar colors to return only colors from
the theme (before it was random hsl)

These changes allow the user to use new colors in tags or charts, the
colors are brighter and with better contrast. We have a full range of
color variations from 1 to 12 where before we only had 4 adaptative
colors.
All these changes will allow us to develop custom themes for the user
soon, where users can choose their accent colors, background colors and
there contrast.
2025-10-29 18:08:51 +00:00
Paul RastoinandGitHub f6f52d676f Explicitly set workspaceId column as uuid type to ease pg LEFT JOIN (#15430)
Pg scan was redundant because historically the workspaceId was
`varchar`, even though below migration won't change that we had a look
to workspaceId col declaration across the codebase
2025-10-29 19:08:44 +01:00
WeikoandGitHub 33545a072c Fix creating kanban view when no select field (#15441)
Adding an early return when no select field exists and you are
redirected to the setting page otherwise it tries to call
setAndPersistViewType with kanban and fails with "No fields for kanban -
should not happen"
2025-10-29 19:04:18 +01:00
martmullandGitHub a6cc80eedd 1751 extensibility twenty sdk v2 use twenty sdk to define a serverless function trigger (#15347)
This PR adds 2 columns handlerPath and handlerName in serverlessFunction
to locate the entrypoint of a serverless in a codebase

It adds the following decorators in twenty-sdk:
- ServerlessFunction
- DatabaseEventTrigger
- RouteTrigger
- CronTrigger
- ApplicationVariable

It still supports deprecated entity.manifest.jsonc 

Overall code needs to be cleaned a little bit, but it should work
properly so you can try to test if the DEVX fits your needs

See updates in hello-world application

```typescript
import axios from 'axios';
import {
  DatabaseEventTrigger,
  ServerlessFunction,
  RouteTrigger,
  CronTrigger,
  ApplicationVariable,
} from 'twenty-sdk';

@ApplicationVariable({
  universalIdentifier: 'dedc53eb-9c12-4fe2-ba86-4a2add19d305',
  key: 'TWENTY_API_KEY',
  description: 'Twenty API Key',
  isSecret: true,
})
@DatabaseEventTrigger({
  universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
  eventName: 'person.created',
})
@RouteTrigger({
  universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
  path: '/post-card/create',
  httpMethod: 'GET',
  isAuthRequired: false,
})
@CronTrigger({
  universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
  pattern: '0 0 1 1 *', // Every year 1st of January
})
@ServerlessFunction({
  universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
})
class CreateNewPostCard {
  main = async (params: { recipient: string }): Promise<string> => {
    const { recipient } = params;

    const options = {
      method: 'POST',
      url: 'http://localhost:3000/rest/postCards',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${process.env.TWENTY_API_KEY}`,
      },
      data: { name: recipient ?? 'Unknown' },
    };

    try {
      const { data } = await axios.request(options);

      console.log(`New post card to "${recipient}" created`);

      return data;
    } catch (error) {
      console.error(error);
      throw error;
    }
  };
}

export const createNewPostCardHandler = new CreateNewPostCard().main;

```


### [edit] V2 

After the v1 proposal, I see that using a class method to define the
serverless function handler is pretty confusing. Lets leave
serverlessFunction configuration decorators on the class, but move the
handler like before. Here is the v2 hello-world serverless function:

```typescript
import axios from 'axios';
import {
  DatabaseEventTrigger,
  ServerlessFunction,
  RouteTrigger,
  CronTrigger,
  ApplicationVariable,
} from 'twenty-sdk';

@ApplicationVariable({
  universalIdentifier: 'dedc53eb-9c12-4fe2-ba86-4a2add19d305',
  key: 'TWENTY_API_KEY',
  description: 'Twenty API Key',
  isSecret: true,
})
@DatabaseEventTrigger({
  universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
  eventName: 'person.created',
})
@RouteTrigger({
  universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
  path: '/post-card/create',
  httpMethod: 'GET',
  isAuthRequired: false,
})
@CronTrigger({
  universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
  pattern: '0 0 1 1 *', // Every year 1st of January
})
@ServerlessFunction({
  universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
})
export class ServerlessFunctionDefinition {}

export const main = async (params: { recipient: string }): Promise<string> => {
  const { recipient } = params;

  const options = {
    method: 'POST',
    url: 'http://localhost:3000/rest/postCards',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.TWENTY_API_KEY}`,
    },
    data: { name: recipient ?? 'Unknown' },
  };

  try {
    const { data } = await axios.request(options);

    console.log(`New post card to "${recipient}" created`);

    return data;
  } catch (error) {
    console.error(error);
    throw error;
  }
};

```


### [edit] V3

After the v2 proposal, we don't really like decorators on empty classes.
We decided to go with a Vercel approach with a config constant

```typescript
import axios from 'axios';
import { ServerlessFunctionConfig } from 'twenty-sdk';

export const main = async (params: { recipient: string }): Promise<string> => {
  const { recipient } = params;

  const options = {
    method: 'POST',
    url: 'http://localhost:3000/rest/postCards',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.TWENTY_API_KEY}`,
    },
    data: { name: recipient ?? 'Unknown' },
  };

  try {
    const { data } = await axios.request(options);

    console.log(`New post card to "${recipient}" created`);

    return data;
  } catch (error) {
    console.error(error);
    throw error;
  }
};

export const config: ServerlessFunctionConfig = {
  universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
  routeTriggers: [
  {
    universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
    path: '/post-card/create',
    httpMethod: 'GET',
    isAuthRequired: false,
  }
  ],
  cronTriggers: [
    {
      universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
      pattern: '0 0 1 1 *', // Every year 1st of January
    }
  ],
  databaseEventTriggers: [
  {
    universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
    eventName: 'person.created',
   }
  ]
}

```
2025-10-29 16:51:43 +00:00
Thomas TrompetteandGitHub 75ed5cb3a2 Fix email editor-email discrepancies (#15436)
Fix https://github.com/twentyhq/twenty/issues/15346

- email not centered
- reduced title sizes
- made paragraph line height and margin consistent with editor
- display line jumps

Editor
<img width="1505" height="701" alt="Capture d’écran 2025-10-29 à 16 46
20"
src="https://github.com/user-attachments/assets/5f6c6377-62b2-4697-861e-39a648cd48bb"
/>

Email
<img width="1505" height="648" alt="Capture d’écran 2025-10-29 à 16 46
36"
src="https://github.com/user-attachments/assets/a596acd8-567f-4726-996c-248519b250c5"
/>
2025-10-29 16:10:21 +00:00
Harshit SinghandGitHub be3ceca0a3 Add listkit to tiptap extension in workflow node (#15363)
## Description

- This PR address issue -
https://github.com/twentyhq/core-team-issues/issues/1768
- Added listkit bundle from tiptap which includes BulletList,
orderedList, ListItem and ListKeymap in one single import
- This bundle also includes keyboards shortcuts - `Cmd + Shift + 7` and
`Cmd + Shift + 8` for ordered and bullet list

## Visual Appearance



https://github.com/user-attachments/assets/7eff1233-8503-4854-bad2-2521898bc568


## Why this Approach

- our current version of tiptap is 3.4.2 while the latest is 3.8.0 hence
installing these versions manually would install the latest version of
3.8.0. The issue when downgrading to 3.4.2 was that Version 3.8.0 of
`@tiptap/extension-list` requires `renderNestedMarkdownContent` from
@tiptap/core
but our `@tiptap/core` version 3.4.2 doesn't export this function.
2025-10-29 16:01:54 +01:00
Paul RastoinandGitHub 0070fc10f8 Debug sentry redis integration (#15431) 2025-10-29 15:34:47 +01:00
8f009e66f1 i18n - translations (#15432)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-29 15:20:58 +01:00
Paul RastoinandGitHub c19a799973 Fix view rest api in v2 (#15398)
# Introduction
Initially wanted to reactive the test introduced in
https://github.com/twentyhq/twenty/pull/15393, that was failing because
of direct data source access removing all views ( even seeded one )
which was making the test fail

While doing so discovered a lot of issue with the rest API:
- Rest api wasn't consuming the v2 at all
- Rest api wasn't prepared to handle v2 exceptions
- Rest api did not handled unknown exceptions ( timeout )

Refactored the cleanup of each test to follow black box pattern and
avoid test leakage
2025-10-29 15:07:08 +01:00
nitinandGitHub 28c6edfa1f add validation on widgets grid position and sizing (#15397)
closes https://github.com/twentyhq/core-team-issues/issues/1606

As discussed in DMS -- overlapping is not a concern since the library
handles the collision and handles overlapping widgets (if created
through api) using the compact type vertical (ie, move the widget
vertically to create space)
2025-10-29 14:05:26 +00:00
MarieandGitHub 473efb5dc5 [groupBy] Order by within records (#15404)
Closes https://github.com/twentyhq/core-team-issues/issues/1727

<img width="1415" height="625" alt="image"
src="https://github.com/user-attachments/assets/cd132582-4a95-463c-8946-87b77670e023"
/>
2025-10-29 14:49:10 +01:00
ab10aa356d i18n - translations (#15429)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-29 12:31:42 +01:00
Charles BochetandGitHub 7b70a1bff6 Fix infinite loop on FE (#15415)
Fixes https://github.com/twentyhq/twenty/issues/15369

It's the first time we are hitting this weird behavior on apollo
onCompleted / onError. Theoretically if the reference of the onCompleted
(resp onError) callback is changing, this will trigger a re-run of
onCompleted. But also theretically the reference here is a
recoilCallback so should never change.

As this is synchronous I have move this logic to a sync way
2025-10-29 12:25:23 +01:00
Paul RastoinandGitHub a9fa0c33ff Fix workspace views prefill (#15428) 2025-10-29 12:24:06 +01:00
Paul RastoinandGitHub ab24cae2eb Front references to views as records (#15425) 2025-10-29 12:23:49 +01:00
eaa82af22f i18n - translations (#15423)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-29 11:21:25 +01:00
EtienneandGitHub 0849483d2e Common - Remove feature flag (#15371)
To be done in an other PR, move graphql-query-runner handlers in
common-api-query-runner folder (+ renaming + typing improvments)


Fixes : 
- totalCount on findMany (Rest)
- getAllSelectedFields did not handle composite field (Rest)
- issue with endCursor (Rest)
- args processing for updateOne and createOne (Rest + Gql)
- fix findDuplicates (Gql)
2025-10-29 10:01:52 +00:00
EtienneandGitHub 5ae7674b9d Common - Throttle update + Metrics (#15413) 2025-10-28 19:15:18 +01:00
8d823827da fix: made standard object labels editable (#15388)
Fixes #15302 

## Video ( Fixed ) :

[Uploading
IssueFixed.mov…](https://drive.google.com/file/d/1XNk3i3ae9Wafelqgbj5GujaPAJRQRcQh/view?usp=sharing)

---------

Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-28 19:03:20 +01:00
EtienneandGitHub 7df43d8fe8 Common - Update many fix (#15412) 2025-10-28 18:45:08 +01:00
1590751131 Set formatted before instead of after (#15401)
Soft deletion events use before in event properties. But we set the
after instead, that only contains a few data.

Fixes https://github.com/twentyhq/twenty/issues/15120

Debugging raised an additional issue. UpdateMany, RestoreMany and
SoftDeleteMany were broken for custom objects. The `where` clause was
using "_objectName.id" instead of "objectName.id" during select. That's
why we need to use different where clause between the select of the
existing value and the actual mutation.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-28 17:13:39 +01:00
0d896fdca8 i18n - translations (#15409)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-28 16:21:16 +01:00
nitinandGitHub 0fdf76560d Widget cards (#15387)
figma -
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=79795-372071&t=0Rg3h23G8F7v80cs-0

for the pinned tab column or the left column -- there is only one state
change! -- which, after talks with @Bonapara -- we should try to keep
the same if possible! -- right now, there is no way to test it -- so I
did not add the same

closes -
https://discord.com/channels/1130383047699738754/1430825706643918942 and
https://discord.com/channels/1130383047699738754/1430599763807436870

story QA - 
<img width="1535" height="1239" alt="Screenshot 2025-10-28 at 00 46 23"
src="https://github.com/user-attachments/assets/9293983e-2d08-427b-971f-731e6f1517aa"
/>
2025-10-28 20:25:52 +05:30
Thomas TrompetteGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
da0e5ba342 Support primitive types in filters (#15402)
When using primitive types such as array, number and boolean, we display
a text field in filters because fieldmetadataId is empty. We should
instead support these as we would do for our own fields.

Adding also a fix for https://github.com/twentyhq/twenty/issues/15282

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-10-28 14:13:10 +00:00
98b4e8431b Reset limit to 1 when object is changed (#15354)
Closes #15345 

The issue was that when the `onChange` was called on the Select
component in `WorkflowEditActionFindRecords.tsx`, the limit was being
reset to 1, but it wasn't rendering immediately. The sidebar had to be
closed and reopened.

I have added a `useEffect` as a hack to re-render the
`FormNumberFieldInput` when it's `defaultValue` is changed. I understand
that using `useEffect` is not a good choice. Please suggest a better fix
if any and I will implement it.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-28 15:06:15 +01:00
Baptiste DevessierandGitHub 2f3912aa98 Always use page layout renderer for dashboards (#15403)
🙈
2025-10-28 14:26:17 +01:00
EtienneandGitHub ee6b86b1a8 Common - many fixes (#15395) 2025-10-28 13:33:41 +01:00
EtienneandGitHub 99d73d1d4b Add metric (+fix) (#15400) 2025-10-28 11:57:31 +00:00
Baptiste DevessierandGitHub b9bdb12b3c Hide page layout tab bar when there are less than two tabs to display (#15385)
- DIsplay the tab bar only if more than 1 tabs can be displayed
- Remove the selfDisplayMode feature: the first tab is now considered to
be the pinned tab on record pages


https://github.com/user-attachments/assets/3f61931d-fde4-4065-b646-5b3a7bdebcc0
2025-10-28 17:20:32 +05:30
55224121aa i18n - translations (#15399)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-28 12:17:43 +01:00
Paul RastoinandGitHub 4dbc78285d Remove deprecated view and related workspace entities (#15393)
# Introduction
A while ago we migrated view from workspace to metadata
Their standard objects workspace entities declaration remained we can
now remove them

## Deprecating commands before 1.5
The view migration command from workspace to metadata was introduced in
`1.5.0`. Removing the `baseWorkspaceEntity` make this command obsolete.
If tomorrow twenty handles auto upgrade in latest and a user having an
instance in `1.3.0` starts auto-upgrading he won't be able to migrate
his views ( that's why we should not support upgrade before 1.5 anymore
here )
We will have the same use case with FavoritesFolders
2025-10-28 11:03:49 +00:00
3eb3d8fe2f i18n - translations (#15396)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-28 11:01:09 +01:00
Paul RastoinandGitHub 503a5029da Refactor twenty-front metadata api services for v2 (#15360)
# Introduction
Please first review this PR initial base
https://github.com/twentyhq/twenty/pull/15358
In a nutshell refactored the frontend fetchers to display v2 errors
format smoothly
Please note that the v2 now finished the whole validation and does fail
fast anymore ( summary is hardcoded for the moment )
```json
[
  {
    "extensions": {
      "code": "BAD_USER_INPUT",
      "errors": {
        "cronTrigger": [],
        "databaseEventTrigger": [],
        "fieldMetadata": [
          {
            "errors": [
              {
                "code": "INVALID_FIELD_INPUT",
                "message": "Default value should be as quoted string",
                "value": "",
              },
              {
                "code": "INVALID_FIELD_INPUT",
                "message": "Default value "" must be one of the option values",
                "value": "",
              },
            ],
            "flatEntityMinimalInformation": {
              "id": Any<String>,
              "name": "testField",
              "objectMetadataId": Any<String>,
            },
            "status": "fail",
            "type": "create_field",
          },
        ],
        "index": [],
        "objectMetadata": [],
        "routeTrigger": [],
        "serverlessFunction": [],
        "view": [],
        "viewField": [],
        "viewFilter": [],
        "viewGroup": [],
      },
      "message": "Validation failed for 0 object(s) and 0 field(s)",
      "summary": {
        "invalidCronTrigger": 0,
        "invalidDatabaseEventTrigger": 0,
        "invalidFieldMetadata": 0,
        "invalidIndex": 0,
        "invalidObjectMetadata": 0,
        "invalidRouteTrigger": 0,
        "invalidServerlessFunction": 0,
        "invalidView": 0,
        "invalidViewField": 0,
        "invalidViewFilter": 0,
        "invalidViewGroup": 0,
        "totalErrors": 0,
      },
      "userFriendlyMessage": "Validation failed for 0 object(s) and 0 field(s)",
    },
    "message": "Multiple validation errors occurred while creating fields",
    "name": "GraphQLError",
  },
]
```

## What's done
- `usePersistView` tool ( CRUD )
- renamed `usePersistViewX` tools accordingly ( no more records or core
)
- Now catching a lot of before unhandled exceptions
- refactored each services to handle their own exception handlers and
return either the response or the error within a discriminated union
record

## Result
### Primary entity error 
When performing an metadata operation on a given metadata, if validation
errors occurs we will display each of them in a toast
Here while creating an object metadata.
<img width="700" height="327" alt="image"
src="https://github.com/user-attachments/assets/0c33d13c-c66c-4749-af36-b253abd3449b"
/>

### Related entity error
Still while creating an object
<img width="700" height="327" alt="image"
src="https://github.com/user-attachments/assets/52607788-c4e9-470c-ac8c-23437345ee5c"
/>

### Translated
<img width="700" height="327" alt="image"
src="https://github.com/user-attachments/assets/a7198c20-ae82-47a6-910c-761de9594672"
/>


## Conclusion
This PR is an extract of https://github.com/twentyhq/twenty/pull/15331
close https://github.com/twentyhq/core-team-issues/issues/1776
## Notes
- Not refactor around triggers services as they're not consumed directly
by any frontend services
2025-10-28 10:50:41 +01:00
08e1fc8bca i18n - translations (#15394)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-28 10:00:22 +01:00
Thomas TrompetteandGitHub be08233fa4 Add sort section in find records action (#15340)
https://github.com/user-attachments/assets/020f3e97-316b-41db-b95d-7b938a7f82cf
2025-10-28 09:54:47 +01:00
Raphaël BosiandGitHub 01d8b99c38 Update bar chart design (#15372)
- Implement new dynamic color palettes
- Create custom bar component with rounded edges



https://github.com/user-attachments/assets/8246f16d-0239-4807-bb4a-9647367575f2
2025-10-27 16:46:06 +00:00
GuillimandGitHub e975fbe217 Add the MORPH feature in the LAB (#15126)
PR to publish the morph relation in the lab once we are ready to push it

Fixes https://github.com/twentyhq/core-team-issues/issues/1292
2025-10-27 17:35:43 +01:00
Charles BochetandGitHub 6cf5bd2ed4 Remove old Calendar and Messaging partial/full sync stages (#15380)
Now that all existing and new workspaces have the following syncStage:
- CALENDAR_EVENT_LIST_FETCH_PENDING
- MESSAGE_LIST_FETCH_PENDING

We can fully deprecate the old FULL_CALENDAR_EVENT_LIST_FETCH_PENDING
and PARTIAL_CALENDAR_EVENT_LIST_FETCH_PENDING (full vs partial is now
directly inferred from the presence of a cursor)
2025-10-27 17:35:10 +01:00
GuillimandGitHub 7e1c046e58 morph bug fix (#15370)
Two bug fixes here: 

# MorphRelationOneToManyFieldDisplay
we expect an empty array, not undefined (run time error otherwise)


Fixes `Cannot read properties of undefined (reading 'length'): Cannot
read properties of undefined (reading 'length')` in
**MorphRelationOneToManyFieldDisplay**

```js
morphValuesWithObjectNameSingular.every(
      (morphValueWithObjectNameSingular) =>
        morphValueWithObjectNameSingular.value.length === 0,
    );
```

# create record in table mode
if the record has a relation there is currenlty a bug in production when
it is created. A cache issue.

`Missing field 'companyFoundedId' while writing result `
2025-10-27 17:34:59 +01:00
Baptiste DevessierandGitHub 24349cb729 Enable records layouts for all records except workflows (#15378)
https://github.com/user-attachments/assets/3cb30486-3409-459e-9d60-7f6f31ebe00c
2025-10-27 17:34:21 +01:00
neo773andGitHub d66d972d01 fix invalid condition for google refresh token (#15383) 2025-10-27 17:29:37 +01:00
MarieandGitHub 0e7d18546d [groupBy] Handle relations on groupBy with records (#15379)
Following PR https://github.com/twentyhq/twenty/pull/15307
2025-10-27 15:14:02 +00:00
Paul RastoinandGitHub 1bf40d9dca Fix v2 self relation field creation (#15382)
# Introduction
Fixing self relation field creation in v2
- When computing related flat field to delete on object metadata
deletion that has self relation fields
- On self relation creation validation name availability not searching
for the relation target field of the current object field if it's the
field being validated

## Coverage
- added CUD integration testing on self relation fields

close https://github.com/twentyhq/twenty/issues/15153
2025-10-27 16:07:58 +01:00
c61da3b14a i18n - translations (#15381)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-27 15:01:15 +01:00
nitinandGitHub 347ccef191 New record button on dashboard index page and reorder (#15367)
closes
https://discord.com/channels/1130383047699738754/1430825009773019258 and
https://discord.com/channels/1130383047699738754/1430601431542530249
before: 
index page:

<img width="1187" height="644" alt="Screenshot 2025-10-27 at 12 42 31"
src="https://github.com/user-attachments/assets/9bb0feba-b1e8-4436-a965-0a53abe74364"
/>

record page:
read mode:

<img width="1303" height="823" alt="Screenshot 2025-10-27 at 14 00 35"
src="https://github.com/user-attachments/assets/62e7d18c-8ebd-442f-88a3-7b8bbe200b4e"
/>


edit mode:

<img width="1303" height="824" alt="Screenshot 2025-10-27 at 14 00 52"
src="https://github.com/user-attachments/assets/56c6b172-8847-4a68-a792-9c03dc01fb21"
/>


-----------------------------------------------------------------------------------------------------------------------
after:

index page:

<img width="1186" height="565" alt="Screenshot 2025-10-27 at 12 41 05"
src="https://github.com/user-attachments/assets/4700242b-367b-4fd0-80bc-a1f696f4317c"
/>

record page:
read mode:

<img width="1302" height="823" alt="Screenshot 2025-10-27 at 13 58 58"
src="https://github.com/user-attachments/assets/4f0fe715-f216-4586-a41d-b7e5520f8d4a"
/>

edit mode:

<img width="1300" height="824" alt="Screenshot 2025-10-27 at 13 59 08"
src="https://github.com/user-attachments/assets/cb15f327-7c0c-4b0a-ad2e-f1833c0f0134"
/>
2025-10-27 14:55:06 +01:00
neo773andGitHub dc9d8db770 refactor: extract filter-emails utils into separate files (#15365) 2025-10-27 14:35:21 +01:00
Ranjeet BaraikandGitHub a6d6733842 [DOCKER_COMPOSE] server depends on redis (#15375)
…or Redis service

Fixes - https://github.com/twentyhq/twenty/issues/15312
2025-10-27 13:27:36 +00:00
neo773andGitHub b978b28760 fix gmail access token (#15374) 2025-10-27 12:21:38 +00:00
Paul RastoinandGitHub 267af42412 Centralize v2 errors types in twenty-shared (#15358)
# Introduction
Followup of https://github.com/twentyhq/twenty/pull/15331 ( Reducing
size by concerns )
This PR centralizes v2 format error types in `twenty-shared` and
consuming them in the existing v2 error format logic in `twenty-server`

## Next
This https://github.com/twentyhq/twenty/pull/15360 handles the frontend
v2 format error refactor

## Conclusion
Related to https://github.com/twentyhq/core-team-issues/issues/1776
2025-10-27 09:44:41 +01:00
fdada805de Central european standard timezone update fix test (#15362)
# Introduction
Fixing timezone flaky test, see you in 6 months

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-27 08:32:44 +01:00
d1f8d097b0 i18n - translations (#15361)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-26 09:35:04 +01:00
Abdul RahmanandGitHub 6405097c6b Add Role tab to agent detail page and fix restricted fields permission issue (#15276) 2025-10-26 09:17:37 +01:00
Abdullah.andGitHub 63c261645a fix: nodemailer - email to an unintended domain can occur due to interpretation conflict. (#15356)
Resolves [Dependabot Alert
289](https://github.com/twentyhq/twenty/security/dependabot/289) and a
couple other alerts.

Removed types for `imapflow` since the package ships them internally
now. `yarn.lock` has major changes due to an upgraded AWS SDK
`@aws-sdk/client-sesv2` which is used by Nodemailer 7.

- No breaking changes were introduced in imapflow and mailparser. 
- Nodemailer's breaking change was dropping the legacy SES transport; we
already use the SMTP transport + our own AWS SES client, so nothing else
needs changing.
2025-10-26 07:08:13 +01:00
Kenny VaneetveldeandGitHub 7f911913c7 fix(mcp): Remove jsonSchema wrapper from tool inputSchema for MCP compatibility (#15349)
## Description

Fixes #15348

The Vercel AI SDK serializes tool schemas with a `jsonSchema` wrapper
(`{ jsonSchema: {...} }`), but the Model Context Protocol specification
expects the schema directly (`{ type: 'object', properties: {...} }`).

This was causing MCP clients like Claude Desktop to silently reject all
tool definitions as invalid, leaving users with no available tools.

## Changes

Modified `handleToolsListing()` in `mcp.service.ts` to unwrap the
`jsonSchema` key before returning tools to MCP clients.

## Before

```json
{
  "name": "create_company",
  "description": "...",
  "inputSchema": {
    "jsonSchema": {
      "type": "object",
      "properties": {...}
    }
  }
}
```

## After

```json
{
  "name": "create_company",
  "description": "...",
  "inputSchema": {
    "type": "object",
    "properties": {...}
  }
}
```

## Testing

Tested with:
- Direct curl request to verify schema format
- Claude Desktop client via mcp-proxy
- Verified tools now appear correctly in MCP clients

## References

- [MCP Tools
Specification](https://modelcontextprotocol.io/specification/2025-06-18/server/tools)
- Related discussion in #12953
2025-10-25 09:59:23 +02:00
aec5b7d99d i18n - translations (#15350)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-24 19:20:15 +02:00
e613b15c5a fix: duplicate merge button bug (#15284)
Fixes - https://github.com/twentyhq/twenty/issues/15263

- Replaced `useLoadSelectedRecordsInContextStore` with
`useLoadMergeRecords` in `useOpenMergeRecordsPageInCommandMenu` for
improved functionality.
- Updated `useMergePreview`, `useMergeRecordsActions`, and
`useMergeRecordsSettings` to utilize `mergeRecordsState` instead of the
deprecated context store hook.
- Cleaned up imports and ensured consistency across merge-related hooks.


https://github.com/user-attachments/assets/453539c9-7f2b-4e8c-bfa1-3ceebca07081

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-24 19:03:11 +02:00
Baptiste DevessierandGitHub 9b2a73d50a Support more standard objects in Record Page Layout (#15288)
Used the `PageLayoutRenderer` for people, opportunities, tasks and
notes.

## Demo


https://github.com/user-attachments/assets/35e61702-f338-47b3-91b7-fd3951a0c967
2025-10-24 17:38:49 +02:00
EtienneandGitHub 93ab1c4118 Throttling in common api (#15338) 2025-10-24 17:32:51 +02:00
MarieandGitHub d7bda9576f [groupBy] Load record within groups (without relations) (#15307)
First step of https://github.com/twentyhq/core-team-issues/issues/1726.
I will handle relations in another PR.
Another ticket is planned to allow for sorting among the records.

When querying records we have set the number of maximum groups to 50,
and of maximum records par group to 10.

<img width="1283" height="798" alt="image"
src="https://github.com/user-attachments/assets/7ffc9805-d715-4017-8030-4f3521e6f741"
/>
2025-10-24 15:30:57 +00:00
WeikoandGitHub 822b4d75a4 CleanOrphanedKanbanAggregateOperationFieldMetadataIdCommand (#15344)
## Context

We want to introduce a FK between view and fieldMetadata through
KanbanAggregateOperationFieldMetadataId so we need to clean up orphan
ones
2025-10-24 17:18:02 +02:00
Abdullah.andGitHub f7a80d250b Update dizzle-kit and drizzle-orm to avoid the dependency on Hono. (#15343)
Updated both drizzle-kit and drizzle-orm to the latest versions.
Process:
- Ran migrations on the database.
- Updated the versions.
- Made the required changes to `drizzle-posgres.config.ts`.
- Ensured migrations are not out of sync be running them again - no
issues, no updates applied.
- Updated the snapshots.
- Deleted the database named `website`.
- Re-ran the migrations to confirm.

There are no breaking changes because the surface drizzle-orm covers is
limited. However, we had to update drizzle-orm in order to update
drizzle-kit to a version greater than 0.27.0 in order to avoid the use
of hono. Therefore, I went ahead and updated both to the latest.

Resolves [Dependabot Alert
#274](https://github.com/twentyhq/twenty/security/dependabot/274) and
three others.
2025-10-24 16:54:15 +02:00
a8d35cb831 i18n - translations (#15342)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-24 16:48:06 +02:00
Antoine MoreauxandGitHub 2fdd15e1d9 test(billing): add assertion for end_date in billing subscription s… (#15341)
…ervice test
2025-10-24 16:39:50 +02:00
e37b8b61ba message channel change 2 (#15269)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-24 16:39:22 +02:00
a937090b5f i18n - translations (#15339)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-24 15:50:10 +02:00
Harshit SinghandGitHub b842da4f13 feat: Add attachment size for attachments (#15330)
## Description

- This PR address issue
https://github.com/twentyhq/core-team-issues/issues/1685
- Added attachment size limit upto 10mb for all google, microsoft and
SMTP provider

## Visual
<img width="348" height="117" alt="Screenshot 2025-10-24 at 5 35 34 PM"
src="https://github.com/user-attachments/assets/19d35b08-9a09-4ad4-aea5-e02cd6552d4d"
/>
2025-10-24 15:44:51 +02:00
Antoine MoreauxandGitHub 5442e9fc37 fix(billing): adapt current phase to current period (#15321)
Fix https://github.com/twentyhq/core-team-issues/issues/1748
2025-10-24 15:44:08 +02:00
Thomas TrompetteandGitHub f65c4e4be9 Missing workspace id in command (#15337)
As title
2025-10-24 15:01:24 +02:00
f1b6ec59cc Align all field-level permissions (#15023)
# Review Issue #14695 on TwentyHQ GitHub

**Twill Task:** https://twill.ai/twentyhq/ENG/tasks/5

## Summary

This PR addresses issue #14695 from the TwentyHQ GitHub repository. The
changes review and implement solutions related to the reported issue.

## Changes Made

- Reviewed issue #14695 and analyzed the problem context
- Implemented necessary fixes or improvements based on issue
requirements
- Updated relevant files and components affected by the issue

## Context

For detailed task context and preview, please refer to the [Twill
task](https://twill.ai/twentyhq/ENG/tasks/5).

---

*Note: Please review the file changes for specific implementation
details.*

<details>
<summary>📸 Screenshots</summary>

Playwright test screenshots captured during development:

### field-permissions-after-fix.png


![field-permissions-after-fix.png](https://storage.googleapis.com/twill-screenshots-twill-469020/screenshots/1760092866977-field-permissions-after-fix.png)

### field-permissions-table-with-fix.png


![field-permissions-table-with-fix.png](https://storage.googleapis.com/twill-screenshots-twill-469020/screenshots/1760092867665-field-permissions-table-with-fix.png)

</details>

---------

Co-authored-by: Twill <agent@twill.ai>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-24 15:01:00 +02:00
682bbe7bba i18n - translations (#15335)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-24 14:48:19 +02:00
WeikoandGitHub a5708c7289 fix migrations (#15336) 2025-10-24 14:47:47 +02:00
EtienneandGitHub 10f4f1592f Common - Update one/many, restore one/many, findDuplicates & mergeMany (#15279)
closes https://github.com/twentyhq/core-team-issues/issues/1739
2025-10-24 12:41:17 +00:00
8f60f7e277 i18n - translations (#15334)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-24 14:39:27 +02:00
Charles BochetandGitHub 2cccb4899e Fix on Morph RelationFieldDisplay (#15333) 2025-10-24 14:27:17 +02:00
GuillimandGitHub b46dc44a95 morph Board mode (#15249)
Here's a concise PR description for your changes:

---

## Fix morph relation fields showing placeholder in kanban view

**Problem:** Morph relation fields always displayed placeholders in
kanban view even when records were selected, because
`useRecordFieldValue` was checking the base field name (e.g.,
`"favorite"`) instead of the computed morph field names (e.g.,
`"favoriteCompany"`).

**Solution:** Modified `useRecordFieldValue` to accept an optional
`fieldDefinition` parameter and added special handling for morph
relations that uses
`recordStoreMorphManyToOneValueWithObjectNameFamilySelector` and
`recordStoreMorphOneToManyValueWithObjectNameFamilySelector` to
correctly retrieve values. Updated `useIsFieldEmpty` to pass the field
definition through, enabling proper empty state detection for morph
relation fields.

**Impact:** Morph relation fields now correctly display their values in
kanban board cards instead of showing placeholders.

Fixes https://github.com/twentyhq/core-team-issues/issues/1323

<img width="681" height="420" alt="Screenshot 2025-10-22 at 14 11 07"
src="https://github.com/user-attachments/assets/de357379-ebff-42c6-bb93-1f0c43ce086d"
/>
2025-10-24 11:54:21 +00:00
721e180fd0 i18n - translations (#15328)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-24 13:46:05 +02:00
Abdullah.andGitHub d3812c9c1f fix: elliptic's private key extraction in ECDSA upon signing a malformed input (#15326)
Fixes [Dependabot Alert
175](https://github.com/twentyhq/twenty/security/dependabot/175) and
four other associated alerts.

Used `yarn up elliptic --recursive` to update the version of elliptic to
6.6.1.
2025-10-24 13:26:26 +02:00
Abdullah.andGitHub 1120107b34 Remove unused dependencies from root package.json. (#15323)
These removed dependencies are not being imported anywhere in the code
base.

Both `twenty-server` and `twenty-front` build properly, ensuring the
dependent packages like `twenty-emails`, `twenty-ui`, `twenty-shared`
etc are building properly.
2025-10-24 13:16:11 +02:00
Abdullah.andGitHub 5d28b32b8e fix: tar-fs has a symlink validation bypass if destination directory is predictable with a specific tarball (#15325)
Fixes [Dependabot Alert
281](https://github.com/twentyhq/twenty/security/dependabot/281) and
five other associated alerts.

Used `yarn up tar-fs --recursive` to update the version of tar-fs to
3.1.1.
2025-10-24 13:15:02 +02:00
Charles BochetandGitHub 9294c07c97 Fix task creation (#15318)
Fix: https://github.com/twentyhq/twenty/issues/15278
2025-10-24 13:14:33 +02:00
c7c671f3e1 Introduce a command to regenerate search vectors for standard and custom objects to fix accent issue. (#15175)
Legacy workspaces still hold the old stored expression, which omits
public.unaccent_immutable, so their tsvectors remain accented and can’t
match the new, unaccented queries. Metadata sync doesn’t touch
asExpression, so only a targeted drop/recreate fixes the underlying
column.

In simpler words, the search vector should contain `mader` instead of
`mäder` for the search to work properly. Therefore, this command
regenerates the search vector across every object that uses
`SEARCH_FIELDS_FOR_*`.

Note that dashboard has a searchVector, but breaks the pattern of using
`SEARCH_FIELDS_FOR_DASHBOARD`. If you look at
packages/twenty-server/src/modules/dashboard/standard-objects/dashboard.workspace-entity.ts:116,
the searchVector field is hard-coded as

```
asExpression: `to_tsvector('english', title)`
```

Therefore, the following code snippet.

```
    const storedExpression = hasAsExpressionSetting(
      searchVectorFieldMetadata.settings,
    )
      ? searchVectorFieldMetadata.settings.asExpression
      : undefined;

    if (storedExpression) {
      return storedExpression;
    }

    return undefined;
```

It checks whether the searchVector field already carries its own
asExpression value in metadata. If the settings object includes that
string, it returns it so the upgrade can reuse the existing expression
for objects that aren’t in our predefined lists. If not, it returns
undefined, signaling there’s no stored expression to fall back on.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-24 10:16:23 +00:00
Eli RibbleandGitHub 238be84336 Stop parsing the PG_DATABASE_URL, use it directly (#15310)
Addresses https://github.com/twentyhq/twenty/issues/15274

There's no need to parse the URL, since psql is happy to use it
directly. If you are going to parse the URL, you should parse it
correctly - the logic removed here make a number of assumptions about
the URL that are inaccurate and reject many types of valid URIs.

This does drop the ability to create the database which may be handy for
people that don't do database administration. For people that do, this
is an anti-feature.
2025-10-24 10:19:37 +02:00
4220bba69b feat(auth): integrate captcha validation and component for sign-in/up… (#15054)
… process

Added captcha token validation to the sign-in/up flow. Introduced
`StyledLoaderContainer` for better UI feedback during loading. Enhanced
error handling within `useSignInUp` to handle GraphQL errors
effectively.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-24 10:13:52 +02:00
06a195af41 [Dashboards] - Tabs reordering (#14798)
closes https://github.com/twentyhq/core-team-issues/issues/1544

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-23 17:28:00 +00:00
Raphaël BosiandGitHub f301f07e43 Convert number chart to aggregate chart allowing date aggregates (#15294)
- Convert number chart to aggregate chart 
- Allow date aggregates on all charts
- Only allow `EARLIEST` and `LATEST` on Aggregate chart and Gauge chart
- Various design fixes


https://github.com/user-attachments/assets/b5a2239d-7b11-48b5-93e6-98ceffae5cab
2025-10-24 05:48:42 +13:00
Thomas TrompetteandGitHub 6f45c47435 Hide stop run behind flag (#15306)
As title
2025-10-23 16:44:47 +00:00
Félix MalfaitandGitHub bbe16c23bc Add Sentry AI agent monitoring with telemetry configuration (#15301)
This PR implements Sentry's AI agent monitoring by:

- Configuring vercelAIIntegration with recordInputs and recordOutputs
options
- Adding sendDefaultPii to Sentry.init() for better debugging
- Creating a shared AI_TELEMETRY_CONFIG constant to DRY up the telemetry
configuration
- Adding experimental_telemetry to all AI SDK calls (generateText,
generateObject, streamText)

All AI operations are now fully monitored in Sentry with complete
input/output recording for debugging and performance analysis.

Note: Currently on Sentry v9.26.0, which is compatible with this
implementation. No breaking changes from the v9-to-v10 migration guide
were found in the codebase.
2025-10-23 18:06:28 +02:00
Paul RastoinandGitHub 7edfe4bc7a [Followup] Fix defaultValue with enum options update in migration v2 integration test + polish (#15300)
# Introduction
Followup of https://github.com/twentyhq/twenty/pull/15286

- Polish replacing sorting by conditional filter and push
- Integration test
2025-10-23 17:57:41 +02:00
4e767799c6 first step in the show record page with a morph relation. (#15109)
Adds the field on the Show page and side panel for Morph relation
fields.

Updates
`packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/hooks/useOpenMorphRelationOneToManyFieldInput.tsx`
to use the correct `recordPickerInstanceId` when opening the picker so
the helper consistently renders (fixes [core-team-issues
#1324](https://github.com/twentyhq/core-team-issues/issues/1324)).

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-23 15:21:49 +00:00
Abdullah.andGitHub eb2fd7c383 fix: cipher-base is missing type checks, leading to hash rewind and passing on crafted data (#15299)
Fixes [Dependabot Alert
263](https://github.com/twentyhq/twenty/security/dependabot/263) -
cipher-base is missing type checks, leading to hash rewind and passing
on crafted data.

Used `yarn up cipher-base --recursive` to bump up the patch version used
by parent dependencies.
2025-10-23 17:10:37 +02:00
Abdullah.andGitHub 5b0344b502 fix: linkify allows prototype pollution & HTML attribute injection (XSS) (#15291)
Fixes [Dependabot Alert
251](https://github.com/twentyhq/twenty/security/dependabot/251) -
linkify allows prototype pollution & HTML attribute injection (XSS).

Used `yarn up linkifyjs --recursive` to bring the version up to 4.3.2 in
yarn.lock.
2025-10-23 17:10:20 +02:00
Abdullah.andGitHub 8341a76bea fix: sha.js is missing type checks leading to hash rewind and passing on crafted data (#15296)
Fixes [Dependabot Alert
264](https://github.com/twentyhq/twenty/security/dependabot/264) -
sha.js is missing type checks leading to hash rewind and passing on
crafted data.

Used `yarn up sha.js --recursive` to bump up the patch version used by
parent dependencies.
2025-10-23 17:09:55 +02:00
Abdullah.andGitHub 998138093f Move react-email dependencies to their respective packages. (#15295)
Instead of declaring packages at the workplace-level package.json,
moving them into their relevant package-level package.json file.

`twenty-front`, `twenty-server` and `twenty-emails` continue to build
and work fine because of hoisting, but the dependencies now follow the
internal strategy of declaring at the package-level, plus give us a
single source of truth to updating package versions.

`twenty-front` and `twenty-emails` only use `@react-email/components`
while `twenty-server` only depends on `@react-email/render`.
2025-10-23 17:09:33 +02:00
EtienneandGitHub e23f2c9183 Observability - add new counters (#15292)
closes https://github.com/twentyhq/core-team-issues/issues/1741
2025-10-23 16:33:45 +02:00
Paul RastoinandGitHub 0780380fe5 Fix composite field update v2 (#15290)
# Introduction
Fixing composite field update by computing field column type for each of
its properties instead of globally

## Coverage
Added integration tests for each composite field on both successful
`create` and `update`
```ts
Test Suites: 17 passed, 17 total
Tests:       104 passed, 104 total
Snapshots:   14 passed, 14 total
Time:        135.431 s, estimated 143 s
```

## Conlusion
Related to https://github.com/twentyhq/core-team-issues/issues/1753
2025-10-23 16:26:46 +02:00
WeikoandGitHub 3f5efdbabc Fix defaultValue with enum options update in migration v2 (#15286)
## Context
When updating both enum options and defaultValue, the old default might
not be in the new options (or vice versa), causing PostgreSQL constraint
violations regardless of update order.

## Solution
Sort updates to process defaultValue last; before updating options,
temporarily set the new defaultValue in metadata so alterEnumValues
creates the column with the correct default, then skip the redundant
defaultValue update handler.
2025-10-23 16:23:34 +02:00
Thomas TrompetteandGitHub 4effa5351c Allow to stop running workflow (#15270)
https://github.com/user-attachments/assets/599154e4-8743-471b-b05a-721b635bcf4e

On stoppage:
- if no running steps, mark pending as failed and end the workflow
- if running steps, set as stopping and exit. Going to the next step, as
the workflow is not running anymore, it will naturally stop
2025-10-23 13:01:15 +00:00
Paul RastoinandGitHub 1cf442966d FindAllCoreViews graphql cache operation invalidation in view related v2 action run (#15285)
# Introduction
Adding a view field to a view in v2 would be optimistically rendered by
the front but on refresh would not get persisted.
That's because we cache both:
```ts
      useCachedMetadata({
        cacheGetter: cacheStorageService.get.bind(cacheStorageService),
        cacheSetter: cacheStorageService.set.bind(cacheStorageService),
        operationsToCache: ['ObjectMetadataItems', 'FindAllCoreViews'],
      }),
```
With keys that look like:
```ts
    return `graphql:operations:${operationName}:${workspace.id}:${workspaceMetadataVersion}:${locale}:${queryHash}`;
```

It was functional in v1 as we would be incrementing metadata version
often.

In v2 it gets incremented only if implies an interaction to metadata
object or fields ( will be deprecated in the future though, until we
finish the // run )

The fix was to check if an `view` or related has been processed in the
workspace migration or if we incremented the metadata in order to
manually flush the `findAllCoreViews` redis cache.
2025-10-23 13:38:03 +02:00
MarieandGitHub 389433a6b9 Remove groupBy feature flag (#15281) 2025-10-23 13:35:16 +02:00
Abdullah.andGitHub 9d951757d8 fix: authorization bypass in next.js middleware (#15287)
Fixes [Dependabot Alert
216](https://github.com/twentyhq/twenty/security/dependabot/216) -
authorization bypass in next.js middleware.

Updated `react-email` version from `4.0.3` to `4.0.4`. This bumps up
Next.js to a safer version for the mentioned critical alert. However,
even the latest `react-email` package has not upgraded to Next.js 15.4.7
- the recommended version by dependabot.

Since `react-email` is a devDependency used to preview email templates
during development, it never gets inserted into the production build.
Therefore, I marking the following alerts as `vulnerable code is never
used` with a comment that it never makes it to the production build.

<p align="center">
<img width="1142" height="342" alt="image"
src="https://github.com/user-attachments/assets/50976fd3-b49c-4ee7-ac26-89f505783d55"
/>
</p>

The only other place where we have next imported is twenty-website,
which uses the safe version `14.2.33`.

<p align="center">
<img width="421" height="92" alt="image"
src="https://github.com/user-attachments/assets/fe1e20dc-7483-44f7-bf26-78f7131ccf46"
/>
</p>
2025-10-23 13:34:22 +02:00
Raphaël BosiandGitHub 5e7bdd1e04 Create widget grip and update title color (#15280)
Changed grip size and stoped using IconButton
2025-10-23 09:10:25 +00:00
Paul RastoinandGitHub 2e84c11eae [v2_FIX] Update standard object/field (#15233)
# Introduction
Refactoring the standard overrides dispatcher to only pass over fields
to has to be dispatched in the standardOverrides entry and let the other
side effects resulting from out of standard overrides mutation trigger

Related to https://github.com/twentyhq/core-team-issues/issues/1753

## This allows
- standard field settings, options etc updates and so on

## Remark
- Determine what we should do on object deactivation ( right now in
production we can still access deactivated object relation properties
and so on e.g deactivate opportunities still accessible from a view
field on company ( still have to re-create it as it has been deleted )
=> decided to leave as it is right now, `isActive` could be considered
as uiDeactivated in the end
- We should also add forbidden standard field mutations validation
inside the builder itself ( here we want to early return in the api
input transpiler too as we don't want to spread invalid side effects )
=> or in the end we could just centralize both but it will generate
several errors

## Coverage
```ts
 PASS  test/integration/metadata/suites/object-metadata/successful-update-one-standard-object-metadata.integration-spec.ts
 PASS  test/integration/metadata/suites/field-metadata/successful-update-one-standard-field-metadata.integration-spec.ts
 PASS  test/integration/metadata/suites/object-metadata/failing-update-one-standard-object-metadata.integration-spec.ts
 PASS  test/integration/metadata/suites/field-metadata/failing-update-one-standard-field-metadata.integration-spec.ts

Test Suites: 4 passed, 4 total
Tests:       18 passed, 18 total
Snapshots:   16 passed, 16 total
Time:        8.721 s, estimated 10 s
```

## Update post review
Faced a behavior where updating back the company label to its original
value would result in storing this value in the standard overrides
Refactored both field and object transpilation behavior to rather remove
the standard override value instead and let fallback on original value

Yes it's quite duplicated will factorize once we move this inside the
builder
2025-10-23 11:02:18 +02:00
StephanieJoly4andGitHub 23ae9e5192 QA & final edits of the entire User Guide released this morning (#15245) 2025-10-23 10:14:27 +02:00
martmullandGitHub c395fed26a Set serverlessFunctionLayerId not nullable (#15272)
As title

Existing Null serverlessFunctionLayerIds have been filled with
`upgrade:1-8:fill-null-serverless-function-layer-id` command

See 0 such records in production

<img width="651" height="415" alt="image"
src="https://github.com/user-attachments/assets/9a5868fe-aa8e-4de0-b656-2e732560fd47"
/>
2025-10-23 09:58:52 +02:00
4b846a42a2 feat: Attachement for Send Email workflow node (#15044)
## Description

- This PR addresses the one issue out of
https://github.com/twentyhq/core-team-issues/issues/1685
-  Added backend support for workflow node to support attachement
- updated send email schema, core utility 
- added workflowattachmentRow and workflowsendEmailAttachment file to
handle file attachment in email workflow
- updated Google and Microsoft to use MailComposer which unifies with
SMTP provider and improves mail structure

## Visual Appearance



https://github.com/user-attachments/assets/16478569-0a83-417e-a85e-70e41fe83343

---------

Co-authored-by: martmull <martmull@hotmail.fr>
2025-10-22 16:45:28 +00:00
Raphaël BosiandGitHub e9ab54766c Remove blue border on hover on widgets when not in edit mode (#15268)
https://github.com/user-attachments/assets/5370e068-fc42-4f8c-9ce5-db88ee0f303d
2025-10-22 18:26:50 +02:00
WeikoandGitHub 09958cc42a Add query progress to delete and destroy (#15252)
Fixes https://github.com/twentyhq/twenty/issues/14601
2025-10-22 18:12:05 +02:00
Raphaël BosiandGitHub 95b405edac Add a banner in the side panel to alert if the bar chart has too many bars (#15267)
Closes https://github.com/twentyhq/core-team-issues/issues/1714

- Created `SidePanelInformationBanner` component
- Created a component state `hasWidgetTooManyGroupsComponentState`
- Displayed the banner in the side panel if the state is true



https://github.com/user-attachments/assets/343a4053-f0d5-4e9b-935d-ead191d70eb2
2025-10-22 18:03:00 +02:00
63a75dd182 fix(docs): update guide links (#15265)
- Update user guide links for email integration, notes, tasks, and
API/webhooks sections to reflect new route structure

Currently, navigating using Algolia's search can result in 404s due to
broken links:
<img width="1105" height="601" alt="Screenshot 2025-10-22 at 10 36
55 AM"
src="https://github.com/user-attachments/assets/54ba762c-f616-4029-a100-0eca3f8cbd9e"
/>

Co-authored-by: StephanieJoly4 <stephanie@twenty.com>
2025-10-22 17:36:20 +02:00
Abdullah.andGitHub 2ef0306894 fix: pbkdf2 returns predictable uninitialized/zero-filled memory for non-normalized or unimplemented algos (#15266)
Fixes [Dependabot Alert
243](https://github.com/twentyhq/twenty/security/dependabot/243) -
pbkdf2 returns predictable uninitialized/zero-filled memory for
non-normalized or unimplemented algos.

Used `yarn up pbkdf2 --recursive` to update to the version of pbkdf2 to
`3.1.5` - both the parent packages `crypto-browserify` and `parse-asn1`
list the upgrade as allowed with `^` in their version, so yarn was able
to update the version of those recursive dependencies.
2025-10-22 17:17:19 +02:00
Raphaël BosiandGitHub d2a47f9bab Fix Cmd + K conflict in note when adding a link (cmd+k shortcut) and opening right drawer (#15257)
Closes https://github.com/twentyhq/twenty/issues/14949


https://github.com/user-attachments/assets/c63e95a8-33ad-4307-ad35-4e4464336004
2025-10-22 17:17:14 +02:00
Abdullah.andGitHub 8fab1ee668 fix: axios requests vulnerable to possible SSRF and credential leakage via absolute URL (#15244)
Fixes [Dependabot Alert
211](https://github.com/twentyhq/twenty/security/dependabot/211) - axios
requests vulnerable to possible SSRF and credential leakage via absolute
URL.
2025-10-22 17:15:52 +02:00
Thomas TrompetteandGitHub c04b3722b3 Use array fields in filter steps (#15256)
Fixes https://github.com/twentyhq/twenty/issues/15247

Before - arrays not available
<img width="595" height="403" alt="Capture d’écran 2025-10-22 à 14 32
22"
src="https://github.com/user-attachments/assets/6c7a5fe3-5002-4b06-8ff3-af42f26d0dae"
/>

After
<img width="595" height="403" alt="Capture d’écran 2025-10-22 à 14 32
03"
src="https://github.com/user-attachments/assets/2e00c4f0-9e57-4bd9-94de-2caa0493446d"
/>
2025-10-22 15:01:00 +00:00
EtienneandGitHub dc05f18310 Common api - Destroy and delete queries (#15177)
Done ⬇️ 
Gql : move delete and destroy logic to common
Rest : 
- rename 'delete' handler to 'destroy'
- create soft delete handlers (named 'delete') : one and many
- create destroy many handler
- update doc

--> Rest api gains NEW soft delete one/many + destroy many capabilities

closes : https://github.com/twentyhq/core-team-issues/issues/1579
2025-10-22 16:35:17 +02:00
Abdullah.andGitHub ce87ea88f5 fix: dset prototype pollution vulnerability (#15253)
Fixes [Dependabot Alert
123](https://github.com/twentyhq/twenty/security/dependabot/123) - dset
prototype pollution vulnerability.

Used `yarn up dset --recursive` to update the patch versions. Two parent
packages depend on dset - `@graphql-tools/utils` and `graphql-yoga`.
Both allow patch version updates with `^` - `^3.1.1` and `^3.1.2`.
2025-10-22 16:08:44 +02:00
Abdullah.andGitHub be85f3776f fix: graphql uncontrolled resource consumption vulnerability (#15260)
Fixes [Dependabot Alert
73](https://github.com/twentyhq/twenty/security/dependabot/73) - graphql
uncontrolled resource consumption vulnerability.

Updated the patch version - from 16.8.0 to 16.8.1 - and this patch only
touches the issue identified by the alert.

<p align="center">
<img width="1175" height="472" alt="image"
src="https://github.com/user-attachments/assets/4f809f03-1e63-4412-822c-227712d1e395"
/>
</p>

Manually tested a few mutations, ran test cases, and everything seems to
work fine. Not expecting it to break anything.

Two files changed in the original patch fix:
https://github.com/graphql/graphql-js/commit/8f4c64eb6a7112a929ffeef00caa67529b3f2fcf
2025-10-22 16:07:47 +02:00
martmullandGitHub 033c28a3d5 1750 extensibility twenty sdk v2 use twenty sdk to define an object (#15230)
We maintain jsonc object definition but will deprecate them pretty soon

## Before
<img width="1512" height="575" alt="image"
src="https://github.com/user-attachments/assets/d2fa6ca4-c456-4aa9-a1e3-845b61839718"
/>

## After
<img width="1260" height="555" alt="image"
src="https://github.com/user-attachments/assets/ba72f4cf-d443-4967-913c-029bc71f3f48"
/>
2025-10-22 13:18:23 +00:00
32558673c6 feat: Implement AI Router for Dynamic Agent Selection (#15227)
Adds intelligent routing system that automatically selects the best
agent for user queries based on conversation context.

### Changes:
- Added `routerModel` column to workspace table for configurable router
LLM selection
- Implemented `RouterService` with conversation history analysis and
agent matching logic
- Created router settings UI in AI Settings page with model dropdown
- Removed agent-specific thread associations - threads are now
agent-agnostic
- Added real-time routing status notification in chat UI with shimmer
effect
- Removed automatic default assistant agent creation
- Renamed GraphQL operations from agent-specific to generic (e.g.,
`agentChatThreads` → `chatThreads`)

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-22 15:02:41 +02:00
Raphaël BosiandGitHub 1c27206b41 Use aggregate operations in the widget configuration instead of extended aggregate operations (#15248)
- Use aggregate operations in the widget configuration instead of
extended aggregate operations
- Use aggregate operation from generated graphql in the frontend
2025-10-22 14:19:02 +02:00
pvrnandGitHub 0221ef991e Format pasted JSON in Workflow HttpRequest Action (#15119)
## Context 

The _expected response body_ does not use monaco-editor, so enabling
`formatOnPaste `as mentioned in this
[comment](https://github.com/twentyhq/twenty/issues/13506#issuecomment-3188746787)
didn't fix the issue below. However, the `TextVariableEditor` uses
tiptap editor which has a `handlePaste` option that we can use to format
JSON.
- Issue https://github.com/twentyhq/twenty/issues/13506

## Implementation:

1. Insert the clipboard text at the current selection.
2. Retrieve the full editor content, parse it as JSON and stringify it
with indentation.
3. Re-use the method that transforms the text into `JSONContent`.
4. Replace the root node with the newly formatted `JSONContent`.
5. Update the cursor position based on the type of pasted text.
6. Apply the transaction with `view.dispatch()`

Note: If parsing fails (invalid JSON), the input will fall back to a
normal paste.

## test

Loom:
https://www.loom.com/share/f2e84d078662481f9f9f71fc98b772a1?sid=a649c4e9-8c55-4cbe-b031-7aba60af0e05
2025-10-22 14:17:36 +02:00
martmullandGitHub 2d9e870395 Update self host url message (#15246)
as title
2025-10-22 13:59:18 +02:00
8369168abe feat: display specific action types in workflow side panel tooltips (#15013)
## What I've Implemented

I've added tooltips that show the original action type when you hover
over workflow step icons in the side panel. Now even if you rename an
action to something custom, you can still see what type of action it
actually is by hovering over the icon.

## The Problem This Solves

Before this change, once you renamed a workflow action (like changing
"Create Record" to "Add New Customer"), there was no way to tell what
the original action type was. This made it really confusing when
collaborating with others or when coming back to your own workflows
after some time - you couldn't tell if an action was a "Create Record"
or "Update Record" or something else.

## What Changed

Updated action type labels: Instead of showing just "Action" for all
record operations, the system now shows specific types like "Create
Record", "Update Record", "Delete Record", etc.

Added hover tooltips: When you hover over the action icons in the
workflow side panel, a tooltip appears showing the original action type,
even if you've renamed the step title.

## Before vs After

Before: All actions showed "Action" in the side panel, making it
impossible to distinguish between different types after renaming.

After: Each action shows its specific type in tooltips, so you always
know what you're working with.

This should make workflow management much clearer, especially when
multiple people are collaborating on the same workflow!

Resolves #14878

## Demo Video

See it in action:
https://www.loom.com/share/c0e0ec24e4524d0685b841e9ceb011d0?t=65&sid=dc05e58a-8869-4969-aa67-9772242fe697

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-10-22 10:20:49 +00:00
Abdullah.andGitHub 5121fdd265 chore: body-parser vulnerable to denial of service when url encoding is enabled (#15243)
Fixes [Dependabot Alert
125](https://github.com/twentyhq/twenty/security/dependabot/125) -
body-parser vulnerable to denial of service when url encoding is
enabled.
2025-10-22 11:43:30 +02:00
Abdullah.andGitHub d593eb134b fix: prototype pollution vulnerability in parse-git-config (#15242)
Fixes [Dependabot Alert
203](https://github.com/twentyhq/twenty/security/dependabot/203) -
prototype pollution vulnerability in parse-git-config.

parse-git-config was a dependency for danger@11.3.1, but danger@13.0.4
does not depend on it.
2025-10-22 11:42:24 +02:00
226cc9eb74 [Dashboards] - Min Max range on secondary axis bar charts (#15118)
video QA


https://github.com/user-attachments/assets/70c37188-2398-43de-bbf6-5882bb79940a

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-22 10:51:01 +02:00
Baptiste DevessierandGitHub c6addc2bb4 Implement basic edition for record page layouts (#15237)
1. Add actions for record page layouts to side panel
2. Support drag-and-drop of widgets


https://github.com/user-attachments/assets/c4cef7c5-08a8-4999-b8a5-e1831cc66709
2025-10-22 10:48:09 +02:00
PurvaPandGitHub c2a477a9d6 [DOCS] Error Workaround twenty-server start on WSL - JavaScript heap out of memory (#15047)
This PR updates the troubleshooting documentation to address Javascript
heap out of memory error during first start of the twenty-server. Here's
a summary of the key changes:

- Added new workaround in troubleshooting.mdx addressing heap out of
memory error during twenty-server:start on WSL
2025-10-22 10:43:02 +02:00
Raphaël BosiandGitHub c8fe805ea5 Connect the number chart to the backend (#15229)
https://github.com/user-attachments/assets/e8fecb5d-bc9b-425a-9c19-baca15f88b1c
2025-10-22 10:20:08 +02:00
Thomas TrompetteandGitHub bf3c3fc5a5 Workflow command menu fixes (#15234)
- Move trash button to command menu footer
<img width="132" height="102" alt="Capture d’écran 2025-10-21 à 18 12
19"
src="https://github.com/user-attachments/assets/ad6a9374-a28f-4498-b8f3-ca576981693c"
/>

- Add footer to triggers + on missing steps
- Catch step body errors so the user can still delete the step when an
error happens
<img width="529" height="419" alt="Capture d’écran 2025-10-21 à 18 13
17"
src="https://github.com/user-attachments/assets/0ac07511-f4ad-40c4-98f1-afb53c0f7a89"
/>
2025-10-22 10:17:06 +02:00
c5564d9bd0 [BREAKING CHANGE] refactor: Add Entity suffix to TypeORM entity classes (#15239)
## Summary

This PR refactors all TypeORM entity classes in the Twenty codebase to
include an 'Entity' suffix (e.g., User → UserEntity, Workspace →
WorkspaceEntity) to improve code clarity and follow TypeORM naming
conventions.

## Changes

### Entity Renaming
-  Renamed **57 core TypeORM entities** with 'Entity' suffix
-  Updated all related imports, decorators, and type references
-  Fixed Repository<T>, @InjectRepository(), and
TypeOrmModule.forFeature() patterns
-  Fixed @ManyToOne/@OneToMany/@OneToOne decorator references

### Backward Compatibility
-  Preserved GraphQL schema names using @ObjectType('OriginalName')
decorators
-  **No breaking changes** to GraphQL API
-  **No database migrations** required
-  File names unchanged (user.entity.ts remains as-is)

### Code Quality
-  Fixed **497 TypeScript errors** (82% reduction from 606 to 109)
-  **All linter checks passing**
-  Improved type safety across the codebase

## Entities Renamed

```
User → UserEntity
Workspace → WorkspaceEntity
ApiKey → ApiKeyEntity
AppToken → AppTokenEntity
UserWorkspace → UserWorkspaceEntity
Webhook → WebhookEntity
FeatureFlag → FeatureFlagEntity
ApprovedAccessDomain → ApprovedAccessDomainEntity
TwoFactorAuthenticationMethod → TwoFactorAuthenticationMethodEntity
WorkspaceSSOIdentityProvider → WorkspaceSSOIdentityProviderEntity
EmailingDomain → EmailingDomainEntity
KeyValuePair → KeyValuePairEntity
PublicDomain → PublicDomainEntity
PostgresCredentials → PostgresCredentialsEntity
...and 43 more entities
```

## Impact

### Files Changed
- **400 files** modified
- **2,575 insertions**, **2,191 deletions**

### Progress
-  **82% complete** (497/606 errors fixed)
- ⚠️ **109 TypeScript errors** remain (18% of original)

## Remaining Work

The 109 remaining TypeScript errors are primarily:

1. **Function signature mismatches** (~15 errors) - Test mocks with
incorrect parameter counts
2. **Entity type mismatches** (~25 errors) - UserEntity vs
UserWorkspaceEntity confusion
3. **Pre-existing issues** (~50 errors) - Null safety and DTO
compatibility (unrelated to refactoring)
4. **Import type issues** (~10 errors) - Entities imported with 'import
type' but used as values
5. **Minor decorator issues** (~9 errors) - onDelete property
configurations

These can be addressed in follow-up PRs without blocking this
refactoring.

## Testing Checklist

- [x] Linter passing
- [ ] Unit tests should be run (CI will verify)
- [ ] Integration tests should be run (CI will verify)
- [ ] Manual testing recommended for critical user flows

## Breaking Changes

**None** - This is a pure refactoring with full backward compatibility:
- GraphQL API unchanged (uses original entity names)
- Database schema unchanged
- External APIs unchanged

## Notes

- Created comprehensive `REFACTORING_STATUS.md` documenting the entire
process
- All temporary scripts have been cleaned up
- Branch: `refactor/add-entity-suffix-to-typeorm-entities`

## Reviewers

Please review especially:
- Entity renaming patterns
- GraphQL backward compatibility
- Any areas where entity types are confused (UserEntity vs
UserWorkspaceEntity)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-22 09:55:20 +02:00
479ac90b1c Full Refresh of the User Guide (#15236)
- Created new sections 
- Added new icons
- Created / Updated articles, focussed on use cases instead of only
features
- Added concrete examples of workflows to set up

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-22 09:37:31 +02:00
BOHEUSandGitHub aba7437fd5 Update documentation (#14891)
Fix small things and update documentation with more troubleshooting
information
2025-10-21 19:02:39 +02:00
EtienneandGitHub 245b0a014a Fix integration test (#15232) 2025-10-21 17:44:25 +02:00
26e432d8e2 fix: Add reserved subdomains constant and update validation on generateSubdomain (#15217)
## Description

Fixes #15160 

- Moved the reserved subdomains to a separate shared constant file:
`packages/twenty-server/src/engine/core-modules/workspace/constants/reserved-subdomains.constant.ts`
- Updated the validation while generating subdomain to check if the
extracted subdomain (from email or display name) is reserved
- When a reserved subdomain is detected, the server will automatically
fall back to a random subdomain

---------

Co-authored-by: Naineel Soyantar <naineelsoyantar@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-21 16:53:48 +02:00
neo773andGitHub 139b6dd29b Preserve all emails, phones, and links when merging records (#15224) 2025-10-21 16:16:22 +02:00
Paul RastoinandGitHub 45473218d3 Field deactivation side effect views calendar kanban viewFields (#15180)
# Introduction
Handling both:
- field deactivation side effect on view fields, view filters and views
- field deactivation side effect on view that targets it as
`kanbanAggregateFieldMetadataId`
- field deactivation side effect on view that targets it as
`calendarFieldMetadataId`

## Coverage
added coverage
```ts
 PASS  test/integration/metadata/suites/field-metadata/kanban-aggregate-field-deactivation-deletes-views.integration-spec.ts (13.132 s)
  kanban-aggregate-field-deactivation-nullifies-kanban-properties
    ✓ should nullify kanban properties when field used as kanbanAggregateOperationFieldMetadataId is deactivated (3923 ms)
    ✓ should not modify views when field not used as kanbanAggregateOperationFieldMetadataId is deactivated (2958 ms)
    ✓ should nullify kanban properties on multiple views when they all use the same field as kanbanAggregateOperationFieldMetadataId (2542 ms)
    ✓ should nullify kanban properties when views have different aggregate operations on same field (3380 ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        13.154 s
```

```ts
 PASS  test/integration/metadata/suites/field-metadata/view-group-field-deactivation-deletes-views.integration-spec.ts (12.639 s)
  view-group-field-deactivation-deletes-views
    ✓ should delete view when field used in view group is deactivated (3469 ms)
    ✓ should not delete view when field not used in view group is deactivated (3109 ms)
    ✓ should delete multiple views when they all use the same field in view groups (2741 ms)
    ✓ should handle deactivation when view has multiple view groups with different fields (3008 ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        12.664 s
```

```ts
 PASS  test/integration/metadata/suites/field-metadata/calendar-field-deactivation-deletes-views.integration-spec.ts (14.579 s)
  calendar-field-deactivation-deletes-views
    ✓ should delete view when field used as calendarFieldMetadataId is deactivated (3388 ms)
    ✓ should not delete view when field not used as calendarFieldMetadataId is deactivated (2438 ms)
    ✓ should delete multiple views when they all use the same field as calendarFieldMetadataId (2635 ms)
    ✓ should handle deactivation when views have different calendar layouts on same field (3195 ms)
    ✓ should delete calendar view but not other view types when calendar field is deactivated (2682 ms)

Test Suites: 1 passed, 1 total
Tests:       5 passed, 5 total
Snapshots:   0 total
Time:        14.601 s, estimated 15 s
```

## View soft deletion
We decided to remove the soft deletion grain on all the views, in this
PR context we've only removed soft deleted validation requirement on any
view entities

## Conclusion

close https://github.com/twentyhq/core-team-issues/issues/1754
2025-10-21 16:12:03 +02:00
Paul RastoinandGitHub 72fd8ae8d2 ci(server): integration server increase shard (#15228) 2025-10-21 16:03:50 +02:00
Félix MalfaitandGitHub f7421c5fc0 Add queue management dashboard (#15202)
Adds a comprehensive queue management interface to the admin panel for
viewing and managing background jobs.

**Features:**
- Queue detail pages showing paginated job lists (50 per page)
- Filter jobs by state: completed, failed, active, waiting, delayed,
paused
- Checkbox selection with bulk actions (delete jobs, retry failed jobs)
- Per-job dropdown menu for individual retry/delete
- Expandable rows showing error messages, stack traces, and job data
- Relative timestamps with hover tooltips
- Display attempt counts on failed jobs
- Dynamic retention policy info from backend

**Changes:**
- Backend: New AdminPanelQueueService with GraphQL endpoints for job
listing, retry, and delete
- Frontend: Queue detail page with QueueJobsTable component
- Updated retention policy: completed jobs kept 4 hours, failed jobs
kept 7 days (max 1000 each)
- Added JobState enum for type safety

<img width="634" height="696" alt="Screenshot_2025-10-20_at_11 45 25"
src="https://github.com/user-attachments/assets/c67bcd27-26cf-47f5-9575-3cd5684d006b"
/>
<img width="484" height="680" alt="Screenshot_2025-10-20_at_11 45 14"
src="https://github.com/user-attachments/assets/68725cc6-b3ec-4098-99ca-f9a717d6f8f1"
/>
<img width="490" height="643" alt="Screenshot_2025-10-20_at_11 45 05"
src="https://github.com/user-attachments/assets/b68a5809-33ff-4452-b48b-741aff7f1dd6"
/>



<img width="685" height="662" alt="Screenshot 2025-10-20 at 13 15 01"
src="https://github.com/user-attachments/assets/eeb5207b-de5c-4b18-bdde-392892053dab"
/>
2025-10-21 16:02:50 +02:00
27f50c4f4e feat: add-create-update-record in workflow (#14654)
## Description

- this PR focuses on issue
https://github.com/twentyhq/core-team-issues/issues/1476
- Added upsert action


## Visual Appearance

<img width="1792" height="1041" alt="Screenshot 2025-10-03 at 12 57
58 PM"
src="https://github.com/user-attachments/assets/57afb96c-d4b3-4a87-95f0-11ac4bd61dd8"
/>




<img width="1792" height="1031" alt="Screenshot 2025-10-03 at 12 57
48 PM"
src="https://github.com/user-attachments/assets/9032d4c2-f0d2-46f1-8682-a7e5c280a303"
/>

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-10-21 15:48:25 +02:00
f5f23a9d31 Fix wrong check (#15179)
as title

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-21 13:05:59 +02:00
e58668003d Support side panel in record page layout (#15216)
## Demo


https://github.com/user-attachments/assets/078b67d3-52d7-4ddf-a65a-fb002f82cfdd

Closes https://github.com/twentyhq/core-team-issues/issues/1731

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-21 13:01:43 +02:00
Raphaël BosiandGitHub ea09987e80 Number chart editor (#15222)
Closes https://github.com/twentyhq/core-team-issues/issues/1620

<img width="1002" height="682" alt="CleanShot 2025-10-21 at 11 49 48@2x"
src="https://github.com/user-attachments/assets/ff06ef0e-ccba-486d-b295-2e5f497f050c"
/>
2025-10-21 10:17:12 +00:00
WeikoandGitHub 0122f805a4 Fix serverless update not saving new code with migration v2 (#15221)
## Context
Regression introduced in https://github.com/twentyhq/twenty/pull/15032
With the new code, we don't have access to the from/to from the
specialised builder anymore and we now rely on diffing result and cache
to create the action which broke serverless update because "code" is not
part of the cache nor part of the diffing (checksum is).
To maintain the existing architecture and keep it generic (by only
modifying the specialized builder), the serverless builder overrides the
parent validateAndBuild method
2025-10-21 11:43:56 +02:00
neo773andGitHub c66261a38b Reuse OAuth access tokens (#15089) 2025-10-21 11:38:49 +02:00
793dc3d6fc Remove dependency on lodash.pick. (#15213)
Fixes [Dependabot Alert
85](https://github.com/twentyhq/twenty/security/dependabot/85) -
prototype pollution in lodash.

Added a shared pick helper (with unit tests) in twenty-shared and
refactored front-end/server code to import { pick } from the shared
barrel instead of lodash.pick.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: martmull <martmull@hotmail.fr>
2025-10-21 08:19:49 +00:00
187cf400aa Fix author attachment field (#15065)
# Migrate Attachment Author to CreatedBy Field

**Twill Task**: https://twill.ai/twentyhq/ENG/tasks/7

## Summary

This PR implements a migration to transition the `Attachment` object
from using an `author` relation field to using the standard `createdBy`
field, addressing issue
https://github.com/twentyhq/core-team-issues/issues/1594.

## Changes

- **Added migration command**
(`1-8-migrate-attachment-author-to-created-by.command.ts`):
- Migrates existing attachment data to use `createdBy` instead of
`author`
- Ensures data integrity during the transition to the standard field
pattern

- **Updated Attachment workspace entity**:
  - Added `createdBy` relation field to the `Attachment` standard object
  - Registered new field ID in `standard-field-ids.ts` constants

- **Integrated migration into upgrade pipeline**:
  - Added migration module for version 1.8
  - Registered in the main upgrade version command module

This change aligns the `Attachment` object with Twenty's standard field
conventions by using the built-in `createdBy` field instead of a custom
`author` field.

---

Fixes https://github.com/twentyhq/core-team-issues/issues/1594

---------

Co-authored-by: Twill <agent@twill.ai>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-21 09:56:28 +02:00
MarieandGitHub 2903e45bef Fix Group by actor field (#15215) 2025-10-20 19:07:35 +02:00
EtienneandGitHub 580ce312fd Common api - Add field create input validation integration testing (#15026)
closes https://github.com/twentyhq/core-team-issues/issues/1624
2025-10-20 18:19:50 +02:00
23d8bbbf92 Refactored WorkflowSendEmailBody to FormAdvancedTextFieldInput (#15157)
Step 1 towards fixing issue #14976 

Refactored WorkflowSendEmailBody to FormAdvancedTextFieldInput For its
reusability across application

- `useEmailEditor` is transformed to `useAdvancedTextEditor`: A
reuseable hook for managing the text editor state and functionality.
- `WorkflowSendEmailBody` is transformed to
`FormAdvancedTextFieldEditor`: A wrapper component for the advanced text
editor.
- `WorkflowSendEmailBody` is transformed to
`FormAdvancedTextFieldInput`: A component integrating the advanced text
editor into forms.
- `ImageBubbleMenu`, `LinkBubbleMenu`, and `TextBubbleMenu`: Contextual
menus for image, link, and text formatting options. are moved to
ui/components for access in FormAdvancedTextFieldInput

Additionally, the email action workflow component was updated to utilize
the new reuseable text editor, enhancing the user experience for
composing emails.

This update also includes storybook entries for the new components to
facilitate testing and documentation.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-20 17:56:49 +02:00
EtienneandGitHub dea08a3a41 Common api - Group by query (#15108)
closes https://github.com/twentyhq/core-team-issues/issues/1626
2025-10-20 17:51:01 +02:00
martmullandGitHub 5186e73ce1 Add .env.example in hello-world app (#15211)
as title
2025-10-20 17:50:23 +02:00
martmullandGitHub 48dd9c3440 Publish twenty-cli 0.1.2 (#15210)
As title
2025-10-20 16:51:01 +02:00
Lucas BordeauandGitHub baf6352eb6 Fix table virtualization data load < 120 records (#15203)
This PR fixes two bugs : 
- Data loading not working between 60 and 120 records on an object
- Table not refreshing when creating a record in an empty table.

Fixes https://github.com/twentyhq/twenty/issues/15196
2025-10-20 16:46:23 +02:00
martmullandGitHub 89da5ee1b4 Fix missing base project files (#15209)
As title

https://www.lexilogos.com/grec_alphabet.htm

<img width="1049" height="542" alt="image"
src="https://github.com/user-attachments/assets/c3faba20-ab53-4a54-afa5-d548b5461c64"
/>
2025-10-20 16:34:39 +02:00
CopilotGitHubcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>DevessierBaptiste Devessier
b4bf0be089 Fix duplicate height properties in styled components (#15200)
## Overview

This PR fixes instances where `height` properties were incorrectly
defined multiple times within the same styled component definitions
across the codebase.

## Problem

Several styled components had duplicate `height` CSS properties where
the exact same property was declared twice in the same selector, causing
confusion and reducing code maintainability. The second declaration
would override the first, making the first one dead code.

## Changes

Fixed 4 files across the codebase:

### Duplicate `height: 100%` Removed
**StyledShowPageRightContainer** in twenty-front:
- `PageLayoutRendererContent.tsx` 
- `ShowPageSubContainer.tsx`
- `PageLayoutRecordPageRenderer.tsx`

Each had `height: 100%` declared twice in the same component definition
(strict duplicates).

### Duplicate `height` with Different Values Removed
**StyledCommandKey** in twenty-ui:
- `MenuItemHotKeys.tsx` - Had both `height: ${({ theme }) =>
theme.spacing(5)}` and `height: 18px` declared. Removed the first
declaration as the second was overriding it.

## Testing

-  ESLint checks pass
-  TypeScript compilation successful
-  CodeQL security analysis - no issues
-  Comprehensive codebase scan confirms no remaining strict height
duplicates

## Impact

- **Visual Changes**: None - purely cleanup refactoring
- **Performance**: No runtime impact
- **Breaking Changes**: None
- **Code Quality**: Improved CSS maintainability by removing dead code

---

**Total:** 4 files modified, 5 lines removed



Created from VS Code via the <a
href="https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github">GitHub
Pull Request</a> extension.

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>

> Hi! It seems that a few styled components in the #codebase are defined
with duplicate `height: 100%`, like in
#file:PageLayoutRendererContent.tsx:27-36.
> 
> Your job is to find all the places where we defined `height: 100%`
incorrectly several times and to keep only one `height` property.


</details>

Created from VS Code via the [GitHub Pull
Request](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github)
extension.

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Devessier <29370468+Devessier@users.noreply.github.com>
Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
2025-10-20 16:33:55 +02:00
WeikoandGitHub 76c2dc020e Add twenty-sdk (#15208) 2025-10-20 15:54:08 +02:00
martmullandGitHub 7723fa70a4 Move schemas to constant folder (#15207)
- move schemas to constants
- increase npm package version
2025-10-20 15:41:53 +02:00
EtienneandGitHub 3aa448d951 release - upgrade next js on twenty website (#15204)
To fix https://github.com/twentyhq/twenty/security/dependabot/216
2025-10-20 13:33:18 +00:00
4e5783eaf4 feat: workflow delay action (Pause - Wait/Sleep/Delay) (#14915)
## Description

- This PR focuses on issue
https://github.com/orgs/twentyhq/projects/1/views/33?pane=issue&itemId=93150683&issue=twentyhq%7Ccore-team-issues%7C20
- added Workflow delay as a Flow action
- for V1 added Type 1: Resume at a specific date or time


## Visual Appearance
<img width="1792" height="1038" alt="Screenshot 2025-10-09 at 5 46
18 PM"
src="https://github.com/user-attachments/assets/e62980e9-59c7-4e5a-b8ec-1e848a462d3f"
/>

<img width="1792" height="1037" alt="Screenshot 2025-10-09 at 5 46
35 PM"
src="https://github.com/user-attachments/assets/7c3f4e39-ab0a-40ed-97a8-4f0cdb86f295"
/>

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-10-20 15:15:55 +02:00
martmullandGitHub 11564f135e Fix env not optional + serverless logging (#15186)
Several fixes after discussing with @BOHEUS 
- set applicationManifest env key optional
- fix server local serverless function logging (introduces a new env
variable `SERVERLESS_LOGS_ENABLED` defaulting to false)
2025-10-20 15:06:26 +02:00
Félix MalfaitandGitHub 3d7f332f80 Change runner for breaking change CI (#15205)
As per title
2025-10-20 13:55:12 +02:00
Charles BochetandGitHub 842c6e6905 Fix dropdowns scroll display (#15199)
I'm applying the scrollbar styling to dropdowns
2025-10-20 11:08:32 +02:00
pvrnandGitHub 3089da5657 Fix Calendar max height (#15127)
## Implementation
- Add height: inherit so the Calendar fits the parent’s height:
https://github.com/twentyhq/twenty/blob/d7e32082628a616d1231d8d3f865ed6871b7f39e/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainer.tsx#L33

- Add `min-height: 1000px `to ensure each week has a minimum height and
to avoid breaking the scroll wrapper on the Y-axis. Similarly to what is
done for the width.
- Issue: https://github.com/twentyhq/twenty/issues/15121

## testing
loom:
https://www.loom.com/share/31c65e62074c4b49979afcd58c856f07?sid=ec56606d-e050-4136-8397-222e14313312
2025-10-19 20:01:40 +02:00
Félix MalfaitandGitHub 18de5c6574 Fix worker health check using wrong Redis connection (#15195)
Health check was connecting to REDIS_URL instead of REDIS_QUEUE_URL
where workers are actually running.
2025-10-19 15:39:50 +02:00
3bec43696f feat: multi role permission intersection (#15150)
Implements permission intersection (AND logic) to prevent permission
escalation when agents act on behalf of users.

### Changes:
- **Permission Intersection**: Operations requiring both user AND agent
permissions
- **RoleContext Type**: Unified type supporting single `roleId` or
multiple `roleIds` for intersection
- **CRUD Services**: Updated to accept `roleContext` for granular
permission control
- **Agent Integration**: Chat agents now use user + agent role
intersection for all operations
- **ORM Layer**: Enhanced `getRepository` to support multi-role
permission checks

### Related:
- Part 2 of ["Acting on behalf of user" concept
PR](https://github.com/twentyhq/twenty/pull/15103)

[Closes #1661](https://github.com/twentyhq/core-team-issues/issues/1661)

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-19 09:30:05 +02:00
f6d133f285 Scaffold all company cards as widgets (#15149)
This PR doesn't support mobile and side-panel modes. The fields tab will
be displayed in these cases.

## Demo


https://github.com/user-attachments/assets/0b2e699c-2b8e-4212-8c75-00d7d2e25237

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-18 22:26:27 +02:00
357a12f902 Fixed advanced filters (#15144)
This PR fixes advanced filters classic in view bar which crashes after
the recent refactor on chart advanced filters.

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-18 21:54:34 +02:00
4b45350430 Add timestamps to GQL fields in useRecordsFieldVisibleGqlFields hook (#15185)
This fixes #15156 

Issue: 
Restore and Destroy buttons not appearing in action menu for deleted
records until the record detail view is opened.

Cause:
The record index/table view queries only fetched fields that were
visible as table columns
The [deletedAt] field (along with [createdAt] and [updatedAt]) was not
included in these queries since it's not a visible column
The action menu logic checks [selectedRecord?.deletedAt] to determine if
a record is deleted and which actions to display
Without the [deletedAt] field in the record store, the action menu
couldn't detect deleted records
Opening the detailed view would fetch all fields (including
[deletedAt]), which is why the buttons would appear afterward

Solution
Modified [useRecordsFieldVisibleGqlFields] to always include the
standard fields ([createdAt], [updatedAt], [deletedAt]) in record index
queries, regardless of column visibility. This ensures the action menu
can immediately detect deleted records

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-18 14:25:39 +02:00
Félix MalfaitandGitHub 5375a478db Fix: Make CI .env manipulation robust against missing trailing newlines (#15189)
## Problem

CI workflow started timing out on October 14, 2025 after commit
`d750df7fff` removed the trailing newline from `.env.example`.

## Root Cause

When `.env.example` lacks a trailing newline:
```bash
# Last line without newline
# CLICKHOUSE_URL=...twenty
```

And CI runs:
```bash
echo "NODE_PORT=3002" >> .env
```

Result:
```bash
# CLICKHOUSE_URL=...twentyNODE_PORT=3002  ← Commented out!
```

Server starts on default port 3000 instead of 3002, health check fails.

## Fix

1. **Restore trailing newline** to `.env.example`
2. **Make all CI `.env` operations robust** by adding `echo "" >> .env`
before appending
3. **Simplified `set_env_var`** function to always add newline first

Now works regardless of whether template files have trailing newlines.

## Files Changed

- 6 CI workflow files
- 1 .env.example file
2025-10-18 13:46:56 +02:00
Félix MalfaitandGitHub 44aee860d9 Consolidate Prettier config and improve consistency (#15191)
## Summary

Clean up and consolidate formatting configuration across the monorepo.

## Changes

### 1. Remove Redundant Configs
-  Delete `packages/twenty-server/.prettierrc` (had invalid
`brakeBeforeElse` typo)
-  Delete `packages/twenty-zapier/.prettierrc`
-  Use root `.prettierrc` only (Prettier searches up directory tree
automatically)

### 2. Improve Root Prettier Config
- Change `endOfLine: 'auto'` → `'lf'` for consistent Unix line endings
across all OSes

### 3. Enhance VSCode Settings
- `files.eol: 'auto'` → `'\\n'` (consistent with Prettier)
- Add `files.insertFinalNewline: true` (explicit editor behavior)
- Add `files.trimTrailingWhitespace: true` (cleaner files)

### 4. Add `.gitattributes`
- Enforce LF line endings at Git level
- Prevents `core.autocrlf` from converting based on contributor's OS
- Mark patch files as binary (they have mixed line endings by design)
- Explicitly define binary file types

### 5. Fix Line Endings
- Convert 3 selectable-list state files from CRLF → LF
- These were the only source files with Windows line endings

## Why These Changes Matter

**Before:**
- 3 different Prettier configs (inconsistent, one had typo)
- Mixed CRLF/LF depending on contributor's OS
- No Git-level enforcement

**After:**
- Single source of truth for formatting
- All files use LF (Unix standard)
- Git enforces line endings regardless of OS
- Prettier warning about invalid option removed

## Result

-  Single `.prettierrc` config
-  Consistent LF line endings enforced by Git
-  Better VSCode defaults
-  No more CRLF files sneaking in from Windows contributors
2025-10-18 12:24:35 +02:00
Félix MalfaitandGitHub d76abefdee Fix CI concurrency: prevent test cancellation on main branch (#15188)
## Problem
The concurrency rules in CI workflows were cancelling in-progress test
runs even on the main branch. This caused inconsistent check counts when
multiple commits were pushed in quick succession.

## Solution
Updated `cancel-in-progress` in all CI workflows to be conditional:
- **On main branch**: Tests run to completion (no cancellation)
- **On feature branches**: Tests are cancelled when new commits are
pushed (saves CI resources)

## Changes
Modified 11 workflow files to use:
```yaml
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
```

This ensures every commit to main gets fully tested while maintaining
efficiency on feature branches.
2025-10-18 10:50:54 +02:00
a3f9657b73 implement "acting on behalf of user" for workflows and agents (#15103)
## Summary
**Step 1 of 2:** Implements the "acting on behalf of user" concept for
workflows and agents to prevent permission escalation and maintain
proper audit trails.

## Problem
Previously, workflows and agents would bypass permissions regardless of
who initiated them, allowing users to escalate their privileges by
triggering workflows that performed actions they couldn't do directly.

## Solution

### For Workflows
Introduced `WorkflowExecutionContext` service that determines execution
mode:
- **Manual triggers/test button**: Uses user's roleId for permissions,
user's identity for `createdBy`
- **Automated triggers** (cron, database events, webhooks): Bypasses
permissions, uses workflow identity

### For Agents
**In Chat:**
- Always act on behalf of the user
- Use user's roleId for permission checks
- Use user's identity for `createdBy`


# Step 1 vs Step 2

###  Step 1 (This PR): Acting on Behalf Concept
- Introduced `isActingOnBehalfOfUser` boolean concept
- Single roleId used for permission checks (user's OR system bypass)
- `createdBy` field properly attributes actions to initiator
- Prevents permission escalation in user-initiated flows

### 🔜 Step 2 (Future): Multi-Role Permission Support
- Support role intersection: `{ intersection: ['roleA', 'roleB'] }`
- Support role union: `{ union: ['roleA', 'roleB', 'roleC'] }`
- Enable user+agent collaboration scenarios
- Update `WorkspaceEntityManager` and `WorkspaceDatasource` to handle
multiple roleIds

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-17 22:56:28 +02:00
EtienneandGitHub 434df8a94c Release - revert/downgrade twenty website next version (#15181)
[PR
#14917](https://github.com/twentyhq/twenty/pull/14917/files#diff-e37dead9533eef25d3a1ac323bb68e93ad2edbb932e972e48f4c756e3c2d5c0f)
upgraded twenty-website to Next.js v15, which requires React 19.
However, the twenty-ui package (imported by twenty-website) uses React
18.2, causing a React version mismatch error.
Solution : Downgrade Next.js from ^15.5.4 to ^14.2.0 to maintain
compatibility with React 18.2 used across the monorepo.
2025-10-17 19:24:27 +02:00
WeikoandGitHub cceeb6ed4d Add applicationId to syncableEntity and fix syncApp deletion (#15170)
## Context
- All flatEntity should extend SyncableEntity
- SyncableEntity should now have applicationId and application relation
- Fix syncApp deletion, should now properly use migration v2 to delete
syncable entities
2025-10-17 17:23:00 +00:00
Félix MalfaitandGitHub 84e7fabaab Squash migration files up to v1.5.5 (#15183)
## Summary

Squash 178 migration files (up to v1.5.5) into 2 consolidated migrations
to significantly improve migration performance.

## Changes

- **Consolidate 169 common migrations** into a single squashed migration
- **Consolidate 11 billing migrations** into a single squashed migration
- **Remove 178 files** (86% reduction: 207 → 29 migration files)
- Make `FK_47a6c57e1652b6475f8248cff78` constraint `DEFERRABLE INITIALLY
DEFERRED` to fix self-referencing foreign key issues
- Preserve all 27 post-v1.5.5 migrations (25 common + 2 billing)

## Impact

-  **2-3x faster** migration execution for new installations
-  **Faster dev environment** setup (database resets)
-  Both `IS_BILLING_ENABLED=false` and `true` modes tested and verified
-  All critical tables and constraints verified

## Testing

- Tested migrations from scratch with billing disabled (26 migrations)
- Tested migrations from scratch with billing enabled (29 migrations)
- Verified all critical tables exist (workspace, user, fieldMetadata,
etc.)
- Verified all 7 billing tables created correctly when enabled
- Confirmed `DEFERRABLE` constraint is properly applied

## Files Changed

- 180 files changed: +443 insertions, -6,462 deletions
- Net reduction: -6,019 lines of code
2025-10-17 18:17:37 +02:00
Paul RastoinandGitHub 3462a2e288 ViewGroup and ViewFilters side effect in v2 (#15096)
# Introduction

### Summary
Implements side effect handling for `ViewGroup` and `ViewFilters` when
field metadata is updated in the v2 architecture. This ensures that
view-related records are properly maintained when enum field options are
modified, deleted, or created.

### Side effects
- **Side Effect System**: Added side effect handling for field metadata
updates that manages related view groups and view filters
- **Enum Field Updates**: When enum field options are modified, the
system now:
- **View Groups**: Creates new groups for added options, updates
existing groups for modified options, and deletes groups for removed
options
- **View Filters**: Updates filter values to reflect option changes and
removes filters that reference deleted options

### Enum runner fix
Update now works for both atomic enum and array enum ( multi select for
instance )

### Compute flat entity maps from to
Standardized this method usage across v2 services
Next step is to require dependencies dynamically

## Conclusion
closes https://github.com/twentyhq/core-team-issues/issues/1649
2025-10-17 17:09:26 +02:00
Félix MalfaitandGitHub 4f1623ff76 Seeding Attachments, Disable ORM Logs, Seeding Parallelization (#15174)
Improvements to database seeding performance and developer experience.

**Changes:**

1. **Attachment seeding**: Add sample files (PDF, XLSX, PPTX, PNG, ZIP)
to dev seeds with proper file storage
2. **Seeding parallelization**: Process entities within batches in
parallel while respecting dependencies
3. **ORM query logging**: Replace manual logger toggling with
`ORM_QUERY_LOGGING` env var
- Values: `disabled` (default), `server-only` (for local dev), `always`
- Configured once in `core.datasource.ts`, removed from all seeder
services

**For .env:**
```bash
ORM_QUERY_LOGGING=server-only
```

Net result: Faster seeding, cleaner code (-68 lines), better local dev
experience.
2025-10-17 16:50:19 +02:00
MarieandGitHub 81bc04d16e Fix settings admin workspace (#15173)
We have a bug in production where activeWorkspace isn't defined and call
to getWorkspaceSchemaName() breaks.
Let's fix it!
2025-10-17 15:59:38 +02:00
9cd957844e Log invalid uuids (#15099)
I had an issue with invalid UUIDs, and I think it would be easier to
find the offending one if the UUID were included in the error message.

This way a database dump can be easily searched.

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-10-17 14:33:33 +02:00
holdgold0andGitHub c554a6afbc Fix invalid UUID/workspaceMemberId error in timeline activity worker (#15074)
This commit fixes a PostgresException error that occurred when
processing timeline activities with empty workspaceMemberId values.

workspaceMemberId appears to be optional but we set it to an empty
string when it is not present. This subsequently causes issues in the
postgres query.

This change fixes the root cause. Empty string handling is added to the
postgres query also for situations where bad data has already entered
the db

Example error
```
[Nest] 34  - 10/13/2025, 9:09:55 PM     LOG [BullMQDriver] Job 2274 with name MessageParticipantMatchParticipantJob processed on queue messaging-queue
query failed: SELECT "timelineActivity"."happensAt" AS "timelineActivity_happensAt", "timelineActivity"."name" AS "timelineActivity_name", "timelineActivity"."properties" AS "timelineActivity_properties", "timelineActivity"."linkedRecordCachedName" AS "timelineActivity_linkedRecordCachedName", "timelineActivity"."linkedRecordId" AS "timelineActivity_linkedRecordId", "timelineActivity"."linkedObjectMetadataId" AS "timelineActivity_linkedObjectMetadataId", "timelineActivity"."id" AS "timelineActivity_id", "timelineActivity"."createdAt" AS "timelineActivity_createdAt", "timelineActivity"."updatedAt" AS "timelineActivity_updatedAt", "timelineActivity"."deletedAt" AS "timelineActivity_deletedAt", "timelineActivity"."workspaceMemberId" AS "timelineActivity_workspaceMemberId", "timelineActivity"."personId" AS "timelineActivity_personId", "timelineActivity"."companyId" AS "timelineActivity_companyId", "timelineActivity"."opportunityId" AS "timelineActivity_opportunityId", "timelineActivity"."noteId" AS "timelineActivity_noteId", "timelineActivity"."taskId" AS "timelineActivity_taskId", "timelineActivity"."workflowId" AS "timelineActivity_workflowId", "timelineActivity"."workflowVersionId" AS "timelineActivity_workflowVersionId", "timelineActivity"."workflowRunId" AS "timelineActivity_workflowRunId" FROM "workspace_8h07bh3zq5pjg65lx9qbxbgg0"."timelineActivity" "timelineActivity" WHERE ( (("timelineActivity"."noteId" IN ($1, $2)) AND ("timelineActivity"."name" IN ($3, $4)) AND ("timelineActivity"."workspaceMemberId" IN ($5, $6)) AND ("timelineActivity"."createdAt" > $7)) ) AND ( "timelineActivity"."deletedAt" IS NULL ) ORDER BY "timelineActivity"."createdAt" DESC LIMIT 1 -- PARAMETERS: [null,"aa6f2e7f-16b1-447f-9988-0ba359358609","linked-note.created","note.created","",null,"2025-10-13T20:59:55.267Z"]
error: error: invalid input syntax for type uuid: ""
/app/packages/twenty-server/dist/src/engine/twenty-orm/error-handling/compute-twenty-orm-exception.js:36
            throw new _postgresexception.PostgresException(error.message, errorCode);
                  ^

PostgresException [Error]: invalid input syntax for type uuid: ""
    at computeTwentyORMException (/app/packages/twenty-server/dist/src/engine/twenty-orm/error-handling/compute-twenty-orm-exception.js:36:19)
    at WorkspaceSelectQueryBuilder.getMany (/app/packages/twenty-server/dist/src/engine/twenty-orm/repository/workspace-select-query-builder.js:56:76)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async WorkspaceRepository.find (/app/packages/twenty-server/dist/src/engine/twenty-orm/repository/workspace.repository.js:33:24)
    at async TimelineActivityRepository.findRecentTimelineActivities (/app/packages/twenty-server/dist/src/modules/timeline/repositories/timeline-activity.repository.js:68:16)
    at async TimelineActivityRepository.upsertTimelineActivities (/app/packages/twenty-server/dist/src/modules/timeline/repositories/timeline-activity.repository.js:27:42) {
  code: '22P02'
}
```
2025-10-17 14:24:05 +02:00
EtienneandGitHub 023c330698 Release - Fix migration message command (#15148) 2025-10-17 13:27:05 +02:00
Paul RastoinandGitHub e91b0a4b15 [CLI-E2E-CI] Fix dependency graph (#15167)
# Introduction

Fixed the build dependency leading to twenty-server start failing before
building,
Removed redundant steps
Make everything run on test db
2025-10-17 13:17:48 +02:00
martmullandGitHub bc336a9fdc Fix migration file (#15168)
as title
2025-10-17 13:16:23 +02:00
Thomas TrompetteandGitHub 91b54e7e68 Remove iterator feature flag (#15165)
As title
2025-10-17 09:19:39 +00:00
martmullandGitHub d2e7f2a910 1635 extensibilitytwenty cli app vars (#15143)
- Update twenty-cli to support application env variable definition
- Update twenty-server to create a new `core.applicationVariable` entity
to store env variables and provide env var when executing serverless
function
- Update twenty-front to support application environment variable value
setting

<img width="1044" height="660" alt="image"
src="https://github.com/user-attachments/assets/24c3d323-5370-4a80-8174-fc4653cc3c22"
/>

<img width="1178" height="662" alt="image"
src="https://github.com/user-attachments/assets/c124f423-8ed8-4246-ae5b-a9bd6672c7dc"
/>

<img width="1163" height="823" alt="image"
src="https://github.com/user-attachments/assets/fb7425a3-facc-4895-a5eb-8a8e278e0951"
/>

<img width="1087" height="696" alt="image"
src="https://github.com/user-attachments/assets/113da8a2-5590-433c-b1b3-5ed3137f24ca"
/>

<img width="1512" height="715" alt="image"
src="https://github.com/user-attachments/assets/1d2110b7-301d-4f21-a45c-ddd54d6e3391"
/>

<img width="1287" height="581" alt="image"
src="https://github.com/user-attachments/assets/353b16c6-0527-444c-87d6-51447a96cbc7"
/>
2025-10-17 10:54:38 +02:00
Félix MalfaitandGitHub 54baa47fbb Reserve "trust" subdomain (#15159)
Setting up our SOC2 trust center at this url
2025-10-17 09:47:47 +02:00
neo773andGitHub 709bdc74c3 Add child folders support for Microsoft (#15114) 2025-10-16 22:46:58 +02:00
neo773andGitHub 4e3c37809c Add schema name display in Settings Admin Workspace (#15151) 2025-10-16 22:42:11 +02:00
Abdullah.andGitHub c578dd99b7 Remove cpx from package.json in twenty-ui since it was unused and caused dependabot alert. (#15147)
Fixes [Dependabot Alert
102](https://github.com/twentyhq/twenty/security/dependabot/102) -
uncontrolled resource consumption in braces.

braces@1.8.5 was coming from the cpx@1.5.0 dependency in
packages/twenty-ui/package.json. That release of cpx dragged in
chokidar@1.7.0 → micromatch@2.3.11 → braces@^1.8.2.

Now, even though there are mentions of `braces: "npm:~3.0.2"` in
yarn.lock, it resolves to `3.0.3` since ~ allows latest patch in semver.
2025-10-16 21:45:10 +02:00
ce045db15a Analyze Context of Issue #1586 Using GitHub MCP (#15058)
# Implement "Tidy Up" Action for Workflow Diagram

**Task Link:** https://twill.ai/twentyhq/ENG/tasks/6

## Summary

This PR adds a "Tidy Up" action to the workflow diagram interface,
allowing users to automatically organize and clean up the layout of
workflow nodes and connections.

## Changes Made

- **Added new workflow action**: Created
`TidyUpWorkflowSingleRecordAction` component to provide a UI action for
tidying up workflow diagrams
- **Refactored tidy-up logic**: Extracted core tidy-up functionality
into a reusable `useTidyUp` hook, separating layout logic from workflow
version persistence
- **Updated action menu configuration**: Integrated the new tidy-up
action into `WorkflowActionsConfig` with proper permissions and keyboard
shortcuts
- **Enhanced right-click menu**: Updated
`WorkflowDiagramRightClickCommandMenu` to use the refactored tidy-up
hook
- **Improved hook architecture**: Simplified `useTidyUpWorkflowVersion`
to delegate layout calculations to the new `useTidyUp` hook

## Key Features

- Users can now trigger workflow diagram tidy-up from the action menu
- Consistent tidy-up behavior across both right-click menu and action
menu interfaces
- Better separation of concerns between layout calculation and data
persistence

<details>
<summary>📸 Screenshots</summary>

Playwright test screenshots captured during development:

### command-menu-with-tidy-up-workflow.png


![command-menu-with-tidy-up-workflow.png](https://storage.googleapis.com/twill-screenshots-twill-469020/screenshots/1760356112795-command-menu-with-tidy-up-workflow.png)

### tidy-up-workflow-command-menu.png


![tidy-up-workflow-command-menu.png](https://storage.googleapis.com/twill-screenshots-twill-469020/screenshots/1760356113168-tidy-up-workflow-command-menu.png)

### tidy-up-workflow-error-toast.png


![tidy-up-workflow-error-toast.png](https://storage.googleapis.com/twill-screenshots-twill-469020/screenshots/1760356113407-tidy-up-workflow-error-toast.png)

</details>

---------

Co-authored-by: Twill <agent@twill.ai>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-10-16 16:59:48 +00:00
Thomas TrompetteandGitHub 0d0cce7bb1 Iterators design updates (#15146)
A few fixes :
- add a counter of iteration for nodes that have been run
<img width="601" height="538" alt="Capture d’écran 2025-10-16 à 17 50
07"
src="https://github.com/user-attachments/assets/de9d56ed-3057-4a67-b1d7-b421f644d11d"
/>

- if a node has fail, we should end the workflow even if a step is still
running
- fix position for add node button in iterator loop :
Before


https://github.com/user-attachments/assets/eafeda64-977f-415d-bab4-b7d0c44406b0

After


https://github.com/user-attachments/assets/6ff221a3-b287-45f6-977f-b127f9998692
2025-10-16 16:32:47 +00:00
MarieandGitHub 3dd70aad03 [command fix] Limit migration to workflow versions (#15145)
This migration updates the filter operand values of the workflowVersion
and workflowRuns in order to capitalize them as they should be (the
product works with both deprecated camel case and capitalized). But that
may involve thousands of workflowRuns!
Let's update the command to only update workflowVersion, and update the
cleanWorkflowRuns job to remove workflow runs that are more than 14 days
old.

This way after the command is run, all new workflow runs will have the
new value for the filter operand, and after fourteen days there will be
no trace of the workflow runs with the deprecated filter operand.
2025-10-16 18:03:22 +02:00
Lucas BordeauandGitHub 59004306c9 Connect chart filters to backend (#15133)
This PR connects the chart filters settings page to the backend.

Both for persisting the filters in the chart's configuration and also
for querying with those filters.

I made sure that the filters configuration is reset in the draft if we
change the data source object.
2025-10-16 15:17:01 +00:00
Baptiste DevessierandGitHub 1b6c9e851f Companies show page as record page (#15132)
Example showing two widgets positioned in a vertical list:


https://github.com/user-attachments/assets/cf3e9793-7d80-4cab-b708-aad9f2bca7d8
2025-10-16 16:45:06 +02:00
EtienneandGitHub b2247a7a3d Release - Fix migration channel sync stage command (#15141) 2025-10-16 16:06:14 +02:00
Charles BochetandGitHub 31206e8b92 Retrigger trans (#15142) 2025-10-16 16:02:23 +02:00
Charles BochetandGitHub f98e4501f5 Fix translations (#15140) 2025-10-16 15:54:08 +02:00
9c602e7da7 i18n - translations (#15138)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-10-16 15:23:38 +02:00
Paul RastoinandGitHub c3ace0eb95 Fix sync metadata (#15135) 2025-10-16 13:17:57 +00:00
EtienneandGitHub 5cbaa9f4d7 Release - add command in upgrade command (#15134) 2025-10-16 15:17:49 +02:00
Paul RastoinandGitHub 7c661f47fd e2e test environment fortwenty-cli (#15123)
# Introduction
Defining very first basis of the twenty-cli e2e testing env.
Dynamically generating tests cases based on a list of applications names
that will be matched to stored twenty-apps and run install delete and
reinstall with their configuration on the same instance

We could use a glob pattern with a specific e2e configuration in every
apps but right now overkill

## Notes
- We should define typescript path aliasing to ease import devxp
- parse the config using a zod object

## Some vision on test granularity
Right now we only check that the server sent back success or failure on
below operation. In the future the synchronize will return a report of
what has been installed per entity exactly. We will be able to snapshot
everything in order to detect regressions

We should also be testing the cli directly for init and other stuff in
the end, we could get some inspiration from what's done in preconstruct
e2e tests with an on heap virtual file system

## Conclusion
Any suggestions are more than welcomed !
close https://github.com/twentyhq/core-team-issues/issues/1721
2025-10-16 12:43:43 +00:00
GuillimandGitHub 73399809f4 Fix: only display the objectname in contextual dropdowns if there are multiple objectmetadatanamessingluar (#15130)
Quick bugfix I found

We want this for normal relations :
<img width="260" height="326" alt="Screenshot 2025-10-16 at 13 40 00"
src="https://github.com/user-attachments/assets/1710f0b7-c469-44a7-b62d-9640f4b1cdd5"
/>

Instead we have currently this:
<img width="243" height="284" alt="Screenshot 2025-10-16 at 13 42 07"
src="https://github.com/user-attachments/assets/7b5c3dff-7221-408f-bc53-6254f2c6d4e5"
/>

For morph we still want this :
<img width="370" height="233" alt="Screenshot 2025-10-16 at 13 41 08"
src="https://github.com/user-attachments/assets/488b7e18-fb98-4bd7-a28a-068d4289e0b9"
/>
2025-10-16 11:48:30 +00:00
Abdullah.andGitHub 75ddafec03 chore (security): bump up the axios version in server to resolve a couple dependabot alerts. (#15128)
Fixes [Dependabot Alert
283](https://github.com/twentyhq/twenty/security/dependabot/283) and
[Dependabot Alert
284](https://github.com/twentyhq/twenty/security/dependabot/284) - Axios
vulnerable to Denial-of-Service (DoS) due to missing data size
validation.
2025-10-16 13:39:09 +02:00
Abdullah.andGitHub 6c035ede8a Ensure one export per file for constants of trash-cleanup. (#15110)
Had three constant exports in one file, thus breaking the codebase
pattern.

Moved them to their separate files and fixed imports.
2025-10-16 13:33:53 +02:00
GuillimandGitHub da77cd0cdc Optimistic follow up (#15071)
Fixing optimistic rendering for the morph relation
2025-10-16 10:17:21 +00:00
Thomas des FrancsandGitHub d7e3208262 Release 1.8.0 - Workflow Enhancements (#15125)
## Release 1.8.0

This release introduces three major workflow enhancements:

### Workflow Iterator Node
- Ability to loop through items in workflows
- Process multiple records sequentially
- Perform actions on each item in a collection

### Workflow Bulk Select
- Select multiple records for manual trigger nodes
- Pass several records to workflow execution
- Works seamlessly with the new iterator node

### Workflow Search Node Limit
- Customize search result limit above 1
- Retrieve multiple records in a single search
- Enhanced compatibility with iterator node for processing results

---

Changelog file: `packages/twenty-website/src/content/releases/1.8.0.mdx`
Release date: October 16, 2025
2025-10-16 12:02:51 +02:00
EtienneandGitHub a5790e3967 Release - switch 1.10 to 1.8 (#15124)
Before
<img width="500" height="500" alt="Screenshot 2025-10-16 at 11 38 07"
src="https://github.com/user-attachments/assets/7fb99487-8e18-41e4-b7e1-0951782480c2"
/>
After
<img width="500" height="500" alt="Screenshot 2025-10-16 at 11 37 58"
src="https://github.com/user-attachments/assets/602c188b-0208-4e74-a3b6-5631df1bb968"
/>
2025-10-16 09:48:30 +00:00
GuillimandGitHub 478328129d Morph-settings-relation-form-merge-follow-up (#15122)
🎯 Merge Settings Relation and Morph Relation Forms followup
https://github.com/twentyhq/twenty/pull/15062


Here we fixed some little comments that could have be done earlier in
the main PR
2025-10-16 11:42:47 +02:00
246543912d [Dashboards] - Omit zero values (#15112)
video QA


https://github.com/user-attachments/assets/6391afdd-0714-4202-8db0-f67388fb7582

---------

Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
2025-10-16 15:00:28 +05:30
Charles BochetandGitHub 5586728105 Fix infinite loop on new table (#15111)
https://github.com/user-attachments/assets/7002cd6c-08d9-4ad7-833f-21bc23d5eea2
2025-10-16 10:30:17 +02:00
GuillimandGitHub 20fdb66bd3 Morph-settings-relation-and-morph-merge (#15062)
🎯 Merge Settings Relation and Morph Relation Forms

In the settings, we unify morph and relation into a single form. 

The form now automatically creates 
- a `RELATION` field when 1 destination object is selected 
- or a `MORPH_RELATION` field when 2+ objects are selected. 

Better UI labels (showing object name for single selection, "X Objects"
for multiple), proper field editing controls on destination objects, and
capitalized field labels.

We still make sure the isMorphRelationEnabled feature flag prevents
current users from accessing this feature

Fixes https://github.com/twentyhq/core-team-issues/issues/1589
2025-10-16 09:56:24 +02:00
Thomas TrompetteandGitHub d3f3f991a5 Infer array current item schema (#15115)
This PR allows to infer the schema of the current item of an iterator
step:
- iterator step receive a variable
- added an util that navigate to the array in schema -
navigateOutputSchemaProperty
- use the array value in schema to generate a new schema - used the
existing getFunctionOutputSchema that I renamed and moved to
twenty-shared

Also cleaned a bit the existing schema for AI.

Before


https://github.com/user-attachments/assets/9767fc89-3524-4bfb-b1ab-8abe92084767

After


https://github.com/user-attachments/assets/3650c1d2-14f2-44f9-b10c-e649fe04128d
2025-10-15 16:15:08 +00:00
martmullandGitHub b16ab1b7c9 1518 extensibility front add an application section in settings (#15056)
Protected by IS_APPLICATION_ENABLED featureFlag

Add `Application` section in settings

<img width="301" height="137" alt="image"
src="https://github.com/user-attachments/assets/ee53bdd2-36f6-45c6-8646-17b1e08abf00"
/>


A `settings/applications` route listing all installed applications

<img width="661" height="428" alt="image"
src="https://github.com/user-attachments/assets/69d534c4-4e9e-452a-a3d9-ded0223bb457"
/>

Introduce a new Tag for application managed items

<img width="885" height="759" alt="image"
src="https://github.com/user-attachments/assets/19767be5-61e5-4bd2-a51d-54ed9bfb1923"
/>



A `settings/applications/<application_id>` details setting page listing
all objects, serverlessFunctions and agents created by the application:

<img width="917" height="778" alt="image"
src="https://github.com/user-attachments/assets/7fc056a6-1d73-4242-b2eb-6f8955d8597d"
/>

A `settings/applications/<application_id>/<serverless_function_id>`

<img width="905" height="652" alt="image"
src="https://github.com/user-attachments/assets/56ca0021-26bf-42cb-9abf-34879f16050a"
/>

Add trigger tab in serverless function details (readonly for now)

<img width="899" height="724" alt="image"
src="https://github.com/user-attachments/assets/5eeefa35-f2a4-4fd8-a640-7b5c5891f226"
/>

Set object, serverless and agent setting detail pages readonly for
managed items
<img width="1075" height="859" alt="image"
src="https://github.com/user-attachments/assets/57c73d69-4980-47a2-b752-8dc5ab494530"
/>
<img width="648" height="582" alt="image"
src="https://github.com/user-attachments/assets/5ad5f3f7-3bc3-4e40-870a-4981c6492524"
/>
<img width="982" height="692" alt="image"
src="https://github.com/user-attachments/assets/7ad756c4-5d33-4a0a-9eb8-416c040362b9"
/>
<img width="1077" height="647" alt="image"
src="https://github.com/user-attachments/assets/e086b9f5-4062-4d10-82a9-4023de3cad3f"
/>
2025-10-15 17:13:29 +02:00
WeikoandGitHub c0ed246a03 Add is unique in migration v2 + refactor inferDeletionFromMissingEntities (#15070)
## Goal
- inferDeletionFromMissingEntities is now a map instead of a single
bool, allowing us to parameterise it based on the entity we want to
compare
- Adding index creation/update when field isUnique is set to true and
index deletion when isUnique is false (for now)

close https://github.com/twentyhq/core-team-issues/issues/1346
2025-10-15 16:08:13 +02:00
Lucas BordeauandGitHub 7f8ec35b5d Added dashboard chart advanced filter components (#15095)
This PR adds the components for advanced filters on chart settings.

It also refactors what's in common between this new command menu page
and the workflow advanced filters.
2025-10-15 16:06:15 +02:00
nitinandGitHub bd16c77fed Dashboards followups 2 (#15107)
adding min height and widths on each chart

this Pr address this followups - 
-
https://github.com/twentyhq/core-team-issues/issues/1710#issuecomment-3405312108
- <img width="843" height="38" alt="Screenshot 2025-10-15 at 15 19 27"
src="https://github.com/user-attachments/assets/f33da21f-a605-40f9-b7fa-02be9dff5908"
/>
- <img width="830" height="42" alt="Screenshot 2025-10-15 at 15 19 40"
src="https://github.com/user-attachments/assets/bf6f3783-b5cc-44c0-94a2-029a489c852e"
/>

video QA
before:


https://github.com/user-attachments/assets/28262a7b-531f-4dcb-9047-c587fe3d8af6


after: 


https://github.com/user-attachments/assets/b0fdbc18-3a7e-4c85-98b6-5799d7207bb4
2025-10-15 19:35:56 +05:30
MarieandGitHub 9aa44ef1e8 Fix objectRecord imports (#15113) 2025-10-15 15:33:08 +02:00
41c970e163 Make page layouts less specific (#15102)
This PR makes some hooks/functions/components more generic. I untied
them from dashboards as they will be needed for any page layout type.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-15 14:34:34 +02:00
EtienneandGitHub 4ae299973b Common Api - createOne/Many (#15083)
closes https://github.com/twentyhq/core-team-issues/issues/1578
2025-10-15 12:13:07 +00:00
f65783f900 [GroupBy] Allow sorting in bar chart (#15097)
Closes https://github.com/twentyhq/core-team-issues/issues/1628

From a technical perspective, we can add more ordering options, such as
the ability to combine two sorts on the X axis, e.g. sort by Close date
ASC and then by Sum ASC, which will sort groups that have the same close
date between themselves depending on their sum ASC. @Bonapara could you
provide design if you want this to be implemented (quite short on our
hand i think - maybe in V2 though)?


https://github.com/user-attachments/assets/6ef21fe1-9d8f-43c0-bfa2-f6fc6341cacf

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-10-15 17:41:14 +05:30
nitinandGitHub 436084f8f4 Split bar graph into two distinct horizontal and vertical bars (#15061)
### Summary

Split BAR into VERTICAL_BAR and HORIZONTAL_BAR as separate chart types.

### The Problem

Initially wanted a simple vertical/horizontal toggle for bar charts, but
ran into a GraphQL union type
constraint: union types can't have the same field name with different
nullability.

- Vertical bars need groupByFieldMetadataIdX as required (categories on
X)
- Horizontal bars need groupByFieldMetadataIdY as required (categories
on Y)
  - GraphQL schema generation fails with this setup

### The Solution

Use semantic primaryAxis and secondaryAxis naming that's
orientation-agnostic:

- primaryAxisGroupByFieldMetadataId = main grouping field (e.g.,
"Company Name")
- secondaryAxisGroupByFieldMetadataId = optional secondary grouping
(e.g., "Stage")

These fields have consistent meaning regardless of orientation. The
visual mapping happens at the UI layer:
  - Vertical bars: primary data renders on X-axis, secondary on Y-axis
  - Horizontal bars: primary data renders on Y-axis, secondary on X-axis

Both chart types share the same DTO structure with consistent
nullability.

### What Changed

  - Split GraphType.BAR → VERTICAL_BAR | HORIZONTAL_BAR
- Renamed fields: primaryAxisGroupByFieldMetadataId,
secondaryAxisGroupByFieldMetadataId (+ subfield
  variants)
- useChartSettingsValues(): Maps semantic fields to setting values (no
swapping)
- getBarChartSettings(): Dynamically arranges settings panel based on
orientation
- transformGroupByDataToBarChartData(): Maps semantic fields to Nivo's
layout prop
  
  video QA
  

https://github.com/user-attachments/assets/479061b5-712e-4ca6-9858-95273d1f16c1
2025-10-15 11:38:48 +02:00
StephanieJoly4andGitHub d21be90c5d Updated the visuals to match the format of the other ones (#15106)
- Removed a few visuals that are not necessary in the end (and not used
yet)
- Replaced visuals that were added yesterday with a new version,
matching the expected format
2025-10-15 11:12:51 +02:00
Abdul RahmanandGitHub dfb796ec5e Improvement AI chat error handling (#15035)
- Fixed AI chat failures when tool calls were present in conversation
history
- Improved error handling and user feedback for AI streaming errors



https://github.com/user-attachments/assets/ca85820f-32c0-4f42-86ee-98f4543e6038
2025-10-15 10:31:18 +02:00
neo773andGitHub 7b179806a9 fix: email input auto complete (#15098)
`autoComplete` defaults to `off` which breaks Bitwarden

<img width="1058" height="224" alt="image"
src="https://github.com/user-attachments/assets/432fade7-5a9c-40cb-9e7f-f0942ae56bd2"
/>
2025-10-15 10:28:34 +02:00
cd1b51618e New resize handle on layout grid (#15040)
before - 
<img width="164" height="167" alt="Screenshot 2025-10-12 at 02 14 17"
src="https://github.com/user-attachments/assets/694d625d-0345-4465-b1db-dcb0c7e416c6"
/>

after - 

<img width="118" height="116" alt="Screenshot 2025-10-14 at 18 51 01"
src="https://github.com/user-attachments/assets/fc342b95-fd78-45e1-b0a3-13231cf11b30"
/>

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-10-14 17:27:30 +00:00
d750df7fff Automatically clean up soft-deleted records after X days. (#14862)
Closes #14726

### Added
- `trashRetentionDays` field to workspace entity (default: 14 days)  
- Automated trash cleanup using BullMQ jobs  
- Daily cron (00:10 UTC) that enqueues cleanup jobs for all active
workspaces
- Per-workspace limit: 100k records deleted per day  
- Calendar-based retention: records deleted on day X are cleaned up X+14
days later (at midnight UTC boundaries)

### Architecture
- **Cron (WorkspaceTrashCleanupCronJob):** Runs daily, enqueues jobs in
parallel for all workspaces
- **Job (WorkspaceTrashCleanupJob):** Processes individual workspace
cleanup
- **Service (WorkspaceTrashCleanupService):** Discovers tables with
`deletedAt`, deletes old records with quota enforcement
- **Command:** `npx nx run twenty-server:command
cron:workspace:cleanup-trash` to register the cron

### Testing
- Unit tests for service with 100% coverage of public API  
- Tested quota enforcement, error handling, and edge cases

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-14 18:49:40 +02:00
StephanieJoly4andGitHub bca79f91ac Added 7 visuals for the new user guide (#15094)
added files and new folders, did not remove any
2025-10-14 18:28:33 +02:00
Paul RastoinandGitHub 85a570db6b Fix view group operation by not sending __typename (#15092)
Following https://github.com/twentyhq/twenty/pull/15052
2025-10-14 18:16:20 +02:00
Félix MalfaitandGitHub 9495d07566 Fix: Correct inverted logic in signUpWithoutWorkspace causing 'User already exists' error (#15086)
## Problem

When trying to signup on localhost:3001 with a new random email, users
were getting an error message saying 'User already exists', even though
they were new users.

## Root Cause

The `signUpWithoutWorkspace` method in `sign-in-up.service.ts` had
inverted logic when checking if a user exists. It was using
`findUserByEmailOrThrow` which:
- **Returns the user** if found
- **Throws the provided error** if NOT found

This caused the opposite behavior:
-  **New user (doesn't exist)**: Threw 'User already exists' error
-  **Existing user**: Continued to create duplicate user

## Solution

Changed to use `findUserByEmail` and explicitly check if the user exists
before throwing the appropriate error:

```typescript
const existingUser = await this.userService.findUserByEmail(newUserParams.email);

if (existingUser) {
  throw new AuthException(
    'User already exist',
    AuthExceptionCode.USER_ALREADY_EXIST,
    { userFriendlyMessage: msg`User already exists` },
  );
}
```

This matches the correct pattern already used in `signUpInWorkspace`
(line 431-441 in auth.resolver.ts).

## Changes
- Fixed inverted logic in `signUpWithoutWorkspace` method
- Now correctly validates that user does NOT exist before creating new
user
- Matches the pattern used in `signUpInWorkspace`

## Testing
The fix corrects the logic so that:
-  New users can sign up successfully
-  Existing users get the correct 'User already exists' error
2025-10-14 18:06:24 +02:00
Thomas TrompetteandGitHub 5f1878c96f Simple design for empty node (#15087)
I did an acceptable design for empty node and iterators for release:
- use array field for iterator node. Added an util to stringify arrays
for backward compatibily
- remove icon for empty node
- allow to select a node on empty node selection


https://github.com/user-attachments/assets/b00037a8-aa1d-4784-b973-05973649b46e
2025-10-14 16:58:53 +02:00
Baptiste DevessierandGitHub 23de047787 Extract DashboardCard from ShowPageSubContainer (#15073)
This PR determines the minimal setup required to render dashboards
without errors while extracting them from the record show page. The
ultimate goal is to create a `PageLayoutRenderer` component that takes
any page layout configuration and correctly renders dashboards or record
pages.

Currently, the `DashboardCard` component renders itself the
`PageLayoutRenderer` component. The next step is to reverse the flow of
control and make `PageLayoutRenderer` take a configuration and decide
whether it should render a dashboard or something else.

This PR takes into consideration two comments left by Charles on [the
first PR scaffolding the
refactor](https://github.com/twentyhq/twenty/pull/15021): renaming
`targetRecord` to `targetRecordIdentifier` and adding tests to
`evaluateTabVisibility()`.

## Demo to assert this PR doesn't break everything


https://github.com/user-attachments/assets/b5b99cf3-08fa-43d3-8da1-79018bc63641
2025-10-14 16:09:44 +02:00
Paul RastoinandGitHub 7d747c9876 [REQUIRES_CACHE_FLUSH][GQL_VIEW_GROUP_API_BREAKING_CHANGE] ViewGroup in v2 (#15052)
# Introduction
Adding view-group to core engine v2
Following https://github.com/twentyhq/twenty/pull/15010 ( same pattern )

## What's done
- Created flat-view-group
- flat view group runner
- flat view group builder
- create view group service v2 and input transpilers
- refactor the existing view group resolver to fix standard (
BREAKING_CHANGE on graphql api update especially ) REST stays the same
- refactored the front to consume the mutations autogenerated

close https://github.com/twentyhq/core-team-issues/issues/1665
2025-10-14 15:55:50 +02:00
nitinandGitHub 5fec6a9afc Fix group by y axis "stacked" behaviour (#15081)
also improved seeds
2025-10-14 15:06:50 +02:00
Thomas TrompetteandGitHub 863e3902af Enqueue a new job every 20 step executions (#15068)
To avoid huge workflows to block the worker, we will enqueue a new job
every 20 steps.
This could be more than 20 if there are branches but I think this is
fine, the goal is only to have a limit set.

Also cleaning a bit the code to mark running steps as failed when
workflow fails.

I tested it on a huge workflow:


https://github.com/user-attachments/assets/d7b8e345-d1a1-4467-96fd-92117b500120
2025-10-14 14:20:18 +02:00
Thomas TrompetteandGitHub 650a037f67 Prevent losing form data when workflow is not defined (#15055)
When updating an active version, we :
- create a draft
- update the draft

Issue is that after the creation, workflow is shortly null. So the
component is re-rendered and the form data are lost.
Removing the check on the null allow to keep the form data.
2025-10-13 17:25:08 +02:00
Lucas BordeauandGitHub 7869d80e8e Fixed drop multiple (#15069)
This PR fixes a bug that prevented dropping multiple items from
differents group into one of the groups containing an item of the
selection.
2025-10-13 17:23:44 +02:00
Lucas BordeauandGitHub b3ddc2ddfb Fixed dropping into empty group (#15066)
This PR fixes a bug when dropping into an empty group with the recent
refactor of the drag and drop logic in #14743
2025-10-13 16:51:30 +02:00
Paul RastoinandGitHub bce83c52f0 Increment metadata version only if schema changes v2 (#15064)
# Introduction
After updating a `viewField` in a view the frontend receives a missmatch
metadata version.

That's because the `flatFieldMetadata` needs to be invalidated on a
viewField addition as it contains its primary key in its cache.
Before we would be checking updated flat entity maps, meaning that on a
view field update the flat field metadata maps would also get updated,
but we also invalidate the old v1 cache at the same time. Resuling in a
metadata version missmatch that's not really relevant for the gql schema
integrity

Now we only check if a object or field actions has been processed, if
yes increment the metadata version.
We should deco-relate the v1 object and fields cache from the metadata
version that should only serve as a "Please refresh browser state
because gql schema has mutated"
2025-10-13 16:09:10 +02:00
Lucas BordeauandGitHub 56b0bbcad9 Table virtualization fix (#15060)
- Added readableFields for visible record field selector to take
permission into account
- Force refresh of table virtualization when updating view fields
2025-10-13 15:30:50 +02:00
Charles BochetandGitHub 0dcf6c77b9 Fix workflow run not refreshed (#15063)
Regression introduced by work on loading workflowRun
2025-10-13 15:30:43 +02:00
EtienneandGitHub fc7304bc5a Common api - findMany query (#15004)
Done in this PR : 
- simplify rest input parsing by removing metadata validation (for
filter and orderBy - to add in common) (1st commit)
- simplify result getter handlers signature (array of objectRecord only
for input)


closes https://github.com/twentyhq/core-team-issues/issues/1614
closes https://github.com/twentyhq/core-team-issues/issues/1615
closes https://github.com/twentyhq/core-team-issues/issues/1616
2025-10-13 12:48:50 +00:00
MarieandGitHub 4c7e8444cf Inter-groups orderBy on groupByDimension values (#15024)
Closes https://github.com/twentyhq/core-team-issues/issues/1563.

We now have two inter-group orderBy criteria: one on the aggregate
values, the other on the dimension values.
Ex: I am grouping companies by city and querying the average number of
employees for each group. I can either order the groups by the city
name, or by the average number of employees, or by one then the other.
I could actually also order groups by an aggregated value that I did not
ask for (ex: average ARR), but I cannot order groups by a field value I
did not group records by (ex: country).
[See discord
discussion](https://discord.com/channels/1130383047699738754/1425438213555753050/1425438223097921659)

An example of query variables: 
```
{
  "groupBy": [
    {
      "createdAt": {
        "granularity": "QUARTER_OF_THE_YEAR"
      }
    },
    {"city": true}
  ],
  "orderBy": [
    { 
      "aggregate": {
        "avgEmployees": "DescNullsLast"
      }
    },
    { 
      "aggregate": {
        "percentyEmptyEmployees": "DescNullsLast"
      }
    },
    {
      "city": "AscNullsLast"
    },
    {
      "createdAt": {
        "orderBy": "AscNullsLast",
        "granularity": "QUARTER_OF_THE_YEAR",
      }
    }
  ]
}
```

The aggregate orderBy criteria had already been implemented, but I
updated the implementation to add an "aggregate" key to prefix them, in
order to avoid confusion between the two + for the schema generation not
to break (otherwise we would have an issue when generating
OrderByWithGroupByInput if a user has created a field that has the same
name as an aggregate field, such as avgEmployees).
2025-10-13 09:51:42 +00:00
168e7b16ec Design adjustments on Bar chart (#15028)
- Make the ticks dynamic when we resize the graph
- Fix formatting
- Fix gradient color not working when the index have a space in it
- Fix the maximum number of groups for a grouped by graph
- Update the tooltip design and display the group

Video:


https://github.com/user-attachments/assets/9f304b6c-3dec-4ce2-9127-41d27f393d90

---------

Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
2025-10-13 09:43:06 +00:00
Paul RastoinandGitHub 6188c72f74 Simplify and enhance v2 type devxp (#15032)
# Introduction
This PR introduces a huge type refactor that will leverage dynamic intra
entity optimistic flat maps update in the future and also a more
granular cache invalidation enhancing performances

close https://github.com/twentyhq/core-team-issues/issues/1717
close https://github.com/twentyhq/core-team-issues/issues/1716
close https://github.com/twentyhq/core-team-issues/issues/1643

## What's done

### Comparators centralization
Comparator is now done through global configuration as const for each
metadata names
Thanks to 

Note:
Definition of standard is evolving, standard is now scoped to an app.
Meaning that a manifest should be able to update its own standards
objects but on other app standards ones ? Each synchronizable entities
will have a standardOverrides ?

## Typing refactor

### `AllFlatEntityTypesByMetadataName`

**Single source of truth for the complete type ecosystem**, mapping each
metadata name to its entity types, flat entities, and migration actions:

```typescript
export type AllFlatEntityTypesByMetadataName = {
  fieldMetadata: {
    actions: { created: CreateFieldAction; updated: UpdateFieldAction; deleted: DeleteFieldAction; };
    flatEntity: FlatFieldMetadata;
    entity: FieldMetadataEntity;
  };
  objectMetadata: { /* ... */ };
  // ... all 10 metadata types
};
```

### `ALL_METADATA_NAME_MANY_TO_ONE_RELATIONS`

**Explicitly declares database relationships** between entities with
compile-time validation:

```typescript
export const ALL_METADATA_NAME_MANY_TO_ONE_RELATIONS = {
  viewField: {
    view: 'viewId',
    fieldMetadata: 'fieldMetadataId',
  },
  cronTrigger: {
    serverlessFunction: 'serverlessFunctionId',
  },
  // ... all relations
} as const satisfies MetadataNameAndRelations;
```

### `ALL_FLAT_ENTITY_CONFIGURATION`

**Centralizes comparison and serialization logic** for each metadata
type:

```typescript
export const ALL_FLAT_ENTITY_CONFIGURATION = {
  fieldMetadata: {
    propertiesToCompare: ['name', 'type', 'label', 'defaultValue', /* ... */],
    propertiesToStringify: ['options', 'settings', 'defaultValue'],
  },
  objectMetadata: {
    propertiesToCompare: ['nameSingular', 'namePlural', 'isActive', /* ... */],
    propertiesToStringify: [],
  },
  // ... all metadata types
} as const satisfies AllFlatEntityConfiguration;
```

## Combined Impact

These three configurations work together to create a **strongly-typed,
centrally-managed metadata system**:

1. **`AllFlatEntityTypesByMetadataName`** defines *what exists*
2. **`ALL_METADATA_NAME_MANY_TO_ONE_RELATIONS`** defines *how they
relate*
3. **`ALL_FLAT_ENTITY_CONFIGURATION`** defines *how to compare and
serialize them*

**Result:** Builders and validators become thin wrappers around
type-safe, configuration-driven logic instead of containing scattered,
error-prone manual implementations.

## What's next

### StandardOverrides standardization
Every metadata entity can be a standard one for a workspace if it's an
installed app, which means it might not expose the whole entity api to
be editable through an import dynamically
The standard overrides logic should not be applied to Fields and Objects
but to every entities

At the moment we have a logic of `EDITABLE_PROPERTIES` through the api,
and also `STANDARD_OVERRIDEDABLE_PROPERTIES`
This should be configuration centered like `propertiesToCompare` and
`propertiesToStringify`.
Scoping this PR to two last for the moment. As update dispatch to
standardOverrides could be considered as a side effect prefer waiting to
start the side effect refactor

### Granular Optimistic deprecation
With this new grain at runtime we will be able to add a flat entity and
dispatch its addition to related flat maps, so we don't have to describe
an optimistic method for each flat entity operations

See `addFlatEntityToFlatEntityAndRelatedEntityMapsOrThrow`

Note: Still in wip and included in this PR but about to create a new one
to integrate these utils and remove existing methods

### ValidateBuildAndRun dynamic args typed defintion
We should restrain the devxp to send expected flat maps entity as at
least from to or dependency as we now have the grain both a type lvl and
runtime to do so
It should not be possible in the devxp to forgot adding the views to the
v2 builder when passing the view field anymore ( that would lead to
permanent validation error in view field integrity checks )

## Conclusion
Thanks for reading and reviewing !
Any suggestions are more than welcomed ! ( same as for questions too ! )
2025-10-13 10:31:34 +02:00
Abdul RahmanandGitHub 3a6621ef6c Fix agent sync failing due to non-existent AgentEntity property (#15051) 2025-10-13 10:03:27 +02:00
d6526af302 Move search vector command from 1-7 to 1-10 and make it less verbose. (#14892)
Made the command more explicit for idempotency.

- Drop index explicitly (even though PostgreSQL does it automatically
when a column is dropped, but it might be good practice to account for
any unforeseen failures).
- Drop column.
- Create column.
- Create index (if we reach this point, column has already been created
and no error was thrown).
 
Figured we do not need extra queries to check ObjectMetadata for the
existence of person table on a workspace - we can use the IF EXISTS
syntax instead.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-12 18:25:45 +02:00
7b84db4708 Only fetch steps and trigger for the current workflow version (#15003)
Avoid fetching full steps and trigger for versions that are not the
current version. Because those won't be used anyway. Better for
performances.

Only difficulty was for the `createDraft` mutation. I needed to return
the full created version so I can store it in cache and use it as new
`currentVersion`. Otherwise the current version is considered as
incomplete for a short time, since workflow is fetched separately from
the current version.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-12 18:06:12 +02:00
0fb2d66808 FIX(#15036): arrows in webhooks (#15038)
**Fixes #15036**
Changes:
Centered Webhook URL: The webhook URL is now properly centered within
its table cell.
Conditional Scroll Arrows: The small arrows for horizontal scrolling now
only appear when the webhook URL is longer than the width of the cell.
This prevents the arrows from being displayed for shorter URLs.

Files changed:
1.
`packages/twenty-front/src/modules/settings/developers/components/SettingsWebhooksTable.tsx`
The grid-template-columns of the StyledTableRow component was changed
from a fixed-width layout (444px 68px) to a flexible layout (1fr auto).
This allows the first column, which contains the webhook URL, to grow
and shrink dynamically based on the available space, which is crucial
for proper centering and handling of different URL lengths.
2.
`packages/twenty-front/src/modules/settings/developers/components/SettingsDevelopersWebhookTableRow.tsx`
The overflow property of the StyledUrlTableCell component was changed
from hidden to auto. This ensures that the horizontal scrollbar (the
"small arrows") is only displayed when the content of the cell (the
webhook URL) overflows the cell's width.The redundant
StyledApisFieldTableRow component was removed to simplify the code, as
its styles were being overridden by the parent component.

How to Test
1. Log in to the application.
2. Go to Settings > API & Webhooks.
4. Add a new webhook with a short URL (e.g., http://localhost:3000).
5. Expected Behavior: The URL should be centered within the table cell,
and no scroll arrows should be visible.
6. Add another webhook with a long URL.
7. Expected Behavior: The URL should be centered, and horizontal scroll
arrows should be visible, allowing you
to scroll to see the entire URL.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-12 12:40:22 +02:00
neo773andGitHub 6f49fd1911 Message channel change 1 (#14942) 2025-10-11 18:18:44 +02:00
560e24fa4b Update unique fields on standard field - include soft deleted records (#14562)
Done : 
- migrate standard unique fields (add : -old)
- deactivate defaultWhereClause
- restore soft deleted if upserted (same for contact creation in mailing
sync)

fixes https://github.com/twentyhq/twenty/issues/14443

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-11 15:50:29 +02:00
c681fb7fb6 1658 post mortem 0710 send batch events in webhook (#15022)
Use concurrent calls

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-11 12:48:40 +02:00
68c86871dd 🦣🦣🦣 Table virtualization (#14743)
This big PR implements table virtualization with an offset paging,
allowing a way more fluid UX.

It is a v1 that should be improved in the future with partial data
loading and optimization of the browser display performance of a row.

But with this PR we have the solid enough technical foundation, both
frontend and backend, to get to a smooth table UX.

Fixes and improvements after first successful round of development
(needed to have main clean) :

- [x] Delete should refresh virtualized portion only and reset all table
- [x] Fix add new : top and bottom
- [x] Table empty shouldn’t show when first loading
- [x] Fix d&d
- [x]  Fix sorts
- [x] Fix drag when scrolling after a full virtual page (it throws an
error)
- [x] Si update mais qu’on a un sort ou filter, alors il faut trigger le
refresh
- [x]  Reset scroll position between tables
- [x]  Reset scroll shadows between tables
- [x] Setup d&n for virtual list :
https://github.com/hello-pangea/dnd/blob/main/docs/patterns/virtual-lists.md
- [x]  Full table re-render when entering edit mode
- [x] Clean code and prepare for merge

Fixes https://github.com/twentyhq/core-team-issues/issues/1613 that
contains other bugs to be fixed before merge

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-11 12:08:10 +02:00
nitinandGitHub 720e93a68a Connect the graph title editor (#15039)
closes https://github.com/twentyhq/core-team-issues/issues/1608
2025-10-11 07:56:20 +00:00
EtienneandGitHub 88d8f8e671 Billing - fix credit usage bar readibility (#15037)
Previous display suggested that the progress bar was completely full
(and no remaining credits) when it was actually completely empty.
Minimal value is set in this PR.

<img width="581" height="143" alt="Screenshot 2025-10-10 at 21 32 20"
src="https://github.com/user-attachments/assets/89acfe7f-b142-46cc-a3c6-090f5b2929fa"
/>
2025-10-11 09:06:36 +02:00
448091e81f Optimistic rendering of morph relations (#14997)
The optimistic rendering of a morph relation Is broken. We intend to fix
it here.

- mapping of gql fields


Fixes https://github.com/twentyhq/core-team-issues/issues/1322

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-10 19:11:00 +02:00
GuillimandGitHub 00eef8ba33 adding object name in morph Pickers (#14977)
Morph related PR to implement this
<img width="321" height="288" alt="Screenshot 2025-10-08 at 13 32 45"
src="https://github.com/user-attachments/assets/b58e2caa-2792-43aa-8077-fa6717bfef5d"
/>


Fixes https://github.com/twentyhq/core-team-issues/issues/1308
2025-10-10 18:33:03 +02:00
Raphaël BosiandGitHub f84d0514b7 Remove edit widget button and add on click edition (#15034)
Remove edit widget button and add on click edition when in edit mode

Before:


https://github.com/user-attachments/assets/1579aa35-f67e-4ba5-9500-5999c7b2164b


After:


https://github.com/user-attachments/assets/3c7677ab-57f7-485d-b619-116ea9ec6c06
2025-10-10 16:13:21 +00:00
Raphaël BosiandGitHub b567c6551a Improve and fix source selection in charts (#15033)
- Improvements: Hide advanced objects in a subMenu and order objects
alphabetically

<img width="420" height="944" alt="CleanShot 2025-10-10 at 17 32 59@2x"
src="https://github.com/user-attachments/assets/52d70a97-b037-4ac1-9237-ef3262cac099"
/>

<img width="426" height="1140" alt="CleanShot 2025-10-10 at 17 33 24@2x"
src="https://github.com/user-attachments/assets/932501be-3c5a-45d9-b2fd-938c7f6b2ef9"
/>


- Fix: reset all fields when changing object
2025-10-10 15:49:30 +00:00
Thomas TrompetteandGitHub d4b81dd20f When workflow is completed, mark as failed steps still running (#15030)
As title.
2025-10-10 17:44:12 +02:00
Félix MalfaitandGitHub 938debd83e Refactor record layouts for backend-driven configuration (#15021)
## Refactor: Prepare frontend record layouts for backend-driven
configuration

This PR simplifies and prepares the frontend record layout system for
eventual migration to backend-driven layouts, aligning the architecture
with the existing PageLayout system used for dashboards.

### Key Changes

**Architecture Improvements:**
- Created unified LayoutRenderingContext that works for both record
pages (with targetRecord) and dashboards (standalone)
- Replaced prop drilling with context-based data flow - cards access
targetRecord and isInRightDrawer via context hooks
- Introduced useTargetRecord() helper hook that provides type-safe
access to the current record
- Created generic CardRenderer component that handles configuration
injection and context guards uniformly

**Configuration System:**
- Converted all tab icons from React components to JSON-serializable
strings (e.g., Icon: IconCheckbox → icon: 'IconCheckbox')
- Added configuration field to cards, matching the widget configuration
pattern on the backend
- Created CardConfiguration types system similar to WidgetConfiguration
on the backend
- Moved widget-specific props (like showDuplicatesSection) into
configuration objects

**Code Organization:**
- Extracted visibility evaluation logic into reusable
evaluateTabVisibility() utility
- Organized layouts into dedicated files (one per object:
base-record-layout.ts, company-record-layout.ts, etc.)
- Renamed components to match their purpose: Notes → NotesCard,
Attachments → FilesCard, etc.
- Consolidated card rendering from registry object to direct
getCardComponent() function

**API Alignment:**
- Made ifNoReadPermissionObject an explicit part of TabVisibilityConfig
(follows if* naming convention)
- Removed redundant targetObjectNameSingular from tab-level (now derived
from visibility config)
- Card API now mirrors Widget API (both use type, configuration,
accessed via context)
2025-10-10 16:26:17 +02:00
5013222db4 i18n - translations (#15025)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-10 15:14:18 +02:00
Paul RastoinandGitHub 651ab184a7 [GQL_VIEW_FILTER_API_BREAKING_CHANGE][WHEN_RELEASED_REQUIRES_CACHE_FLUSH] ViewFilter migration to workspace migration v2 (#15010)
# Introduction
Migrating `viewFilter` to v2 in order to migrate later the field update
side effect on view to v2 too

## What's done
- Created flat-view-filter
- flat view filter runner
- flat view filter builder
- create view filter service v2 and input transpilers
- refactor the existing view filter resolver to fix standard (
BREAKING_CHANGE on graphql api update especially ) REST stays the same
- refactored the front to consume the mutations autogenerated

## New generic tools
### Compare two flat entity
Introducing a new util to compare two flat entity, it's strictly typed
and will be added to the generic builder in a following PR
This will ease flat entity addition as won't required to create a
specific abstraction for comparison
Generic builder will expect specific constant: properties to compare and
properties to stringify

### Transform flat entity for comparison
Forked and refactor the initial existing method for flat entity business
scope and type safety

## Coverage
Migrated existing integration tests to fit new contract API
This PR does not add strong coverage on validation exceptions
Deadlines are too short

close https://github.com/twentyhq/core-team-issues/issues/1666
2025-10-10 15:02:14 +02:00
Charles BochetandGitHub 37473175a0 Reduce relation loading overload on FE graphql queries (#14991)
## Problem

With Twenty usage growing, we are facing challenges on server side to
respond to the demand. The current bottleneck we are facing is server
CPU.
While investigating CPU performances, we figured out that loading all
relation fields was the biggest issue.

### About graphql query response size

**Example:** on `People Index` Table page:
we query: `person.company` and we query **all non relation fields** on
company relation field.
`{ person { company { id, name, domainName, employees, address ... } }`
 
 
However we only need **company.id, company.name and company.domainName**
to be able to render the Company Chip in the company column (RELATION)
in the table.
`{ person { company { id, name, domainName } }`

We initially assumed that the querying all non relation fields was not
an issue because it was not adding additional load on database (which is
also partially true: if a field is containing a huge json this will add
load on postgres as data needs to be transfered)
This assumption is wrong on CPU side:
- when loading one to many relations (company.people), this quickly ads
up and we end up with response of 20kB quite quickly, even without
adding any custom field on person.
- even when loading a many to one relation, if the user is storing big
data in a given field (note.body for instance, or workflowRun.state),
this starts also being an issue.
- Worst case scenario are starting to happen: on a production workspace
with 20 active workflows. Loading workflow table while displaying
workflow runs commands (20 workflows x 60 workflowRuns x
workflowRun.state which is a big JSON) result in a response of... 125MB.

### Why is it an issue?

When yoga (graphql engine) parses a response to send it back in server
response, it's using `JSON.parse `(or stringify depending on the case).
Parsing data is CPU instensive (as you need to validate, transform) and
this is more or less `O(n)`.
This means returning 125MB is very intense on the CPU and will likely
use 100% of the CPU for ~1sec in our production servers.

NodeJs (nodeV8) is single threaded. It's able to process multiple
requests in parallel but to do that, it will cut them in "microTasks"
and process each microTasks (that can belong to different requests) one
after the other. Exactly like a single threaded CPU would allocate some
time to a process and then to the next one, etc.

This means that this big response request will actually block the other
request.
As a result, all requests are slow and our infrastructure is multi
tenant so some customers are impacting others.

This is even a bigger issue when our health checks start to fail and
containers are starting being considered as unhealthy and killed by the
orchestrator


## How to fix this

1. On Front end side, we should only query what we need. In this PR, I'm
forcing the relations to only query: `id`, `labelIdentifier`,
`imageIdentifier`
2. (later) as we are API first, we also need to do something to protect
the servers from this side too. To do that, Graphql APIs can associate a
cost to each graphql field (maybe 1 for a test fixed, 2 for a JSON
field, 10 for relations, etc...) and we can throttle based on that.

## Changes in this PR

It's mainly about refactor the tooling to generate `RecordGqlFields`
(`generateDepthOneGqlFields`). this tooling is used to generate the list
of fields we want to query. Most of the time we want to query a record
with one level of nesting.
1) Refactor to remove duplicate code => `generateDepthOne` become
`generateDepth` and can handle both `depth = 0 | 1`

2) Introduce `generateDepthRecordGqlFieldsFromFields.ts` which is the
base and can give you a list of gqlFields based on FieldMetadataItems

3) Introduce `generateDepthRecordGqlFieldsFromObject` which is a
shortcut for an object
4) Introduce `generateDepthRecordGqlFieldsFromRecords` which is the
intersection between `generateDepthRecordGqlFieldsFromObject` and a
given record (useful for cache tooling)
5) Replace all usages + introduce a hook
`useGenerateDepthRecordGqlFieldsFromObject` to ease usage
2025-10-10 14:31:12 +02:00
e235e5f9d7 i18n - translations (#15020)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-10 10:21:35 +02:00
Raphaël BosiandGitHub da165effb7 Improvements on group by option in graph editor (#15014)
- Display sort by for the Y axis only if a group by is selected
- Add the possibility to remove a group by Y
2025-10-10 10:04:18 +02:00
Thomas TrompetteandGitHub cbfd73cbd8 Enable filters in iterators (#15017)
Filters should not cut the whole workflow. These should only stop the
branch. This PR:
- adds a new skipped status 
- when a filter stops, it still goes to the next step
- the next step will execute if there is at least a successful step
- if only skipped step, it will be skipped as well

It allows to use filters in iterators.


https://github.com/user-attachments/assets/1cfca052-55c0-4ce5-9eb8-63736618d082
2025-10-09 23:14:54 +02:00
6f7656f24d i18n - translations (#15019)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-09 22:45:57 +02:00
nitinandGitHub 44f97058ac Tidy up validation for configuration (#14939)
closes https://github.com/twentyhq/core-team-issues/issues/1605

TODO:  
~~- add stories~~
~~- add base graph on companies when creating a new graph widget~~
2025-10-09 20:34:51 +00:00
Abdul RahmanandGitHub 5adc9fe9b2 feat: mutualize CRUD tools between workflows and AI (#14996)
Closes [#1662](https://github.com/twentyhq/core-team-issues/issues/1662)
2025-10-10 00:55:34 +05:30
b508bd8f9d i18n - translations (#15016)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-09 18:38:16 +02:00
Félix MalfaitandGitHub e577c2d746 Update user friendly errors for translations (#15000)
Force msg typing instead of string for user friendly errors
2025-10-09 18:17:32 +02:00
martmullandGitHub 660cd38f35 Add timeoutMs to webhooks calls (#15012)
5 second timeout
tested with an application serverlessFunction that delays
2025-10-09 15:54:44 +00:00
Thomas des FrancsandGitHub 01d40c4f86 website(releases): fix MDX content list to match visible releases (fix offset) (#14904)
# Current behavior

1.7.0 is displayed as 1.6.0

<img width="1303" height="1082" alt="CleanShot 2025-10-06 at 11 23 38"
src="https://github.com/user-attachments/assets/a502aeec-eafc-4db9-bd04-0969a00ca474"
/>

# Fix

Fixes an off-by-one mismatch between rendered releases and compiled MDX
content by generating MDX from the filtered visible releases list. This
ensures versions like 0.2.3, 0.3.0, ... display the correct content.
2025-10-09 17:36:22 +02:00
Raphaël BosiandGitHub ef8cd0ed19 Add middleware boundary padding as a prop in dropdown (#15011)
Add middleware boundary padding as a prop in dropdown + fix bottom end
placement in graph editor
2025-10-09 14:18:22 +00:00
d2ed2ad7b9 i18n - translations (#15009)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-09 15:23:25 +02:00
Paul RastoinandGitHub 59fbe35a8c Move view in metadata-modules/ and create atomic folder + module for each view entity (#14990)
# Introduction
Preparing view-filter and view-group introduction in v2 core engine
Moving view from `core-modules` to `metadata-modules`

## What happened

### Created dedicated modules for each view entity:
- ViewFieldModule
- ViewFilterModule
- ViewFilterGroupModule
- ViewGroupModule
- ViewSortModule

### Each module is now completely independent with its own:
- Controller
- Resolver
- Service
- Entity

### Created dedicated abstraction metadata module folder for:
- flat-view-field
- flat-view

### Dependencies 
- Eleminated circular dep on ViewModule to all others ones
- Granular import not importing the whole viewModule anymore everywhere


close https://github.com/twentyhq/core-team-issues/issues/1703
2025-10-09 15:18:15 +02:00
c9a1a110e1 i18n - translations (#15007)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-09 15:00:33 +02:00
875dc1a6b8 Connect the bar chart to the group by resolver (#14885)
Closes https://github.com/twentyhq/core-team-issues/issues/1535

Video QA:


https://github.com/user-attachments/assets/153fa3f1-08d9-4952-9456-635c602e1f57



https://github.com/user-attachments/assets/d3111afb-4c84-4f57-8a56-5cf666748c86

There are still some formatting and design issues (the labels which are
on top of each other and the values which should be formatted) that will
be fixed in a future PR

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-10-09 14:54:33 +02:00
martmullandGitHub 973b4fef90 Fix Weiko code review returns (#15006)
as title
2025-10-09 14:51:23 +02:00
3c0f1a3a9b i18n - translations (#15002)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-09 13:45:52 +02:00
nitinandGitHub fced148724 Fix widget header shrink and make widget placeholder to change state on click (#14999)
closes closes https://github.com/twentyhq/core-team-issues/issues/1609
2025-10-09 17:06:53 +05:30
martmullandGitHub 5252384f14 1588 serverless follow ups 2 (#14998) 2025-10-09 12:56:59 +02:00
MarieandGitHub ebc6bbabaf [Fix] Command to migrate operand values for workflows (#14849)
In [this PR](https://github.com/twentyhq/twenty/pull/14785) we got rid
of what we now call ViewFilterOperandDeprecated, a camelCase version of
ViewFilterOperand, which we thought we only used in the FE. We did not
notice that this enum was used to persist filters used in workflows,
reflected in workflowVersion and workflowRun.
As a result workflow runs were broken. [In this mitigation
PR](https://github.com/twentyhq/twenty/pull/14837) (and [this
one](https://github.com/twentyhq/twenty/pull/14841)) we updated the code
handle both enum values from ViewFilterOperandDeprecated and
ViewFilterOperand, but we still want to get rid of
ViewFilterOperandDeprecated.

the command in this PR replaces the occurences of enum values of
ViewFilterOperandDeprecated.
When this has been merged, deployed and run on the workspaces, we will
be able to remove ViewFilterOperandDeprecated altogether; that will have
to be done in 1.10 though not before.
2025-10-09 09:45:44 +00:00
martmullandGitHub 920ad4c3f2 Return data or raise error in serverless controller (#14989)
as title
TODO validate we do not need to add a new column
2025-10-08 17:09:25 +00:00
EtienneandGitHub 3b992ed549 Rest/Gql - Filter input - Integration tests (#14836) 2025-10-08 18:42:22 +02:00
9fceb2354e i18n - translations (#14988)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-08 16:35:40 +02:00
Paul RastoinandGitHub 4ecc9c622d [WHEN_RELEASED_REQUIRES_CACHE_FLUSH] Object related record logic in v2 (#14937)
# Introduction
Initial motivation here was to migrate the object related records logic
from v1 to v2, please note that now in v2 views aren't records anymore
but core engine entities

## What's done
- Added specific label identifier targeting view field logic
- Handled side effects on viewField creation with lowest position on
object label identifier mutation
- Added viewField relations in field metadate entity + handled
optimistic in builder v2
- Added view relations in object metadata entity + handled optimistic in
builder v2
- Added integration tests covering the side effects and new validation
exceptions
- Sandardized cache computation
- Coverage on object metadata creation side effect on views and view
fields

## Coverage
```ts
 PASS  test/integration/graphql/suites/view/view-field/object-identifier-update-side-effect-on-view-field.integration-spec.ts
  View Field Resolver - Successful object metadata identifier update side effect on view field
    ✓ should create a view field on label identifier object metadata update if it does not exist on view (7 ms)
    ✓ Should not allow deleting a label identifier view field (17 ms)
    ✓ Should not allow destroying a label identifier view field (6 ms)
    ✓ Should not allow updating a label identifier view field visibility to false (8 ms)
    ✓ Should not allow creating a view field with a position lower than the label idenfitier view field (180 ms)
    ✓ Should not allow updated labelIdentifier view field with a position higher than existing other view field (346 ms)
    ✓ Should allow updated labelIdentifier view field with a position higher than existing other view field (434 ms)

Test Suites: 1 passed, 1 total
Tests:       7 passed, 7 total
Snapshots:   5 passed, 5 total
Time:        4.571 s, estimated 5 s
```

close https://github.com/twentyhq/core-team-issues/issues/1664
2025-10-08 16:23:37 +02:00
1c1739ec80 i18n - translations (#14986)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-08 16:01:09 +02:00
Antoine MoreauxGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
8e83be43fe feat(auth): enhance error handling for sign-up and existing user checks (#14953)
Refactored error handling in `useSignUpInNewWorkspace` and `useSignInUp`
hooks to provide user-friendly messages. Added validation for existing
users during sign-up, updating server-side logic to throw specific
exceptions (`USER_ALREADY_EXIST`).

Fix
https://twenty-v7.sentry.io/issues/6686753138/events/latest/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D%20QueryFailedError&referrer=latest-event&sort=date

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-10-08 13:43:43 +00:00
WeikoandGitHub 2e9779b511 Fix patch yoga cache key (#14983) 2025-10-08 14:51:34 +02:00
martmullandGitHub 15b37ca28c Set twenty-cli version to 0.1.1-alpha (#14982)
as title, to test the deploy cd
2025-10-08 12:38:24 +00:00
WeikoandGitHub a8fd6a0cab Patch yoga cache key (#14981) 2025-10-08 14:37:50 +02:00
f679829b29 i18n - translations (#14980)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-08 14:22:59 +02:00
1d09cb949a Feat/multivalue limit (#14961)
## Summary
1. This change introduces the ability to limit how many values a
multi-value field can contain (for example: maximum number of emails,
phone numbers, links, or array items).
2. It centralizes the limit as a shared constant and type, validates
settings on the server, updates front-end types and components to
consume the setting, and adds a small settings UI so workspace admins
can change the limit per field.
3. Default behavior is preserved: if no max is configured, the existing
default (10) is used.


## **Fixes Issue:** [#14740
](https://github.com/twentyhq/twenty/issues/14740)

## Manual Test Screenshot
<img width="383" height="451" alt="Screenshot 2025-10-08 002413"
src="https://github.com/user-attachments/assets/a7704af6-10ef-4d10-b8c9-a9eeca03bfd9"
/>


### Values in fields


https://github.com/user-attachments/assets/7f59c4f7-3aca-4f83-8c04-3d44988316e3


Let me know if any changes are needed

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-08 12:09:38 +00:00
GuillimandGitHub fbd7e65111 fixing storybook (#14964)
Storybook had  issues. This PR intends to solve them

Main things to care :
I had to change the way the provider was given to the Calendar view. Not
sure how it may impact the final component, so if someone with some
knowledge about it could take a look that would be great

TODO:
Only one remaining test to fix : prefetch loading. Couldn't find out how
to solve this issue. When you open the story you see that the companies
are not fetched.
2025-10-08 14:09:04 +02:00
MarieandGitHub 7419674cac Fix circular dependency at shared package building (#14978)
Fixing 
<img width="708" height="271" alt="Capture d’écran 2025-10-08 à 12 27
12"
src="https://github.com/user-attachments/assets/2f459e2f-146b-4452-8517-59f58b8a33a4"
/>

The circular-chunk warning came from computeRecordGqlOperationFilter.ts
importing from the barrel @/utils, which reexports
turnRecordFilterIntoRecordGqlOperationFilter and friends, creating a
re-export cycle across chunks.
2025-10-08 10:37:59 +00:00
EtienneandGitHub c693c4d9cf Common API - create common find one query (#14720)
closes https://github.com/twentyhq/core-team-issues/issues/1418

Tested : 
- findOne on Rest and Gql

### Vision
#### Common
- Common is kind of renamed Gql base resolver
- Common handles args (filter, values, ...) validation
- Common accepts depth or raw gql selected fields to compute
selectedFields
- Common is directly called by each CommonQueries (findOne, ...)
service, which extend CommonBaseQuery service
- Common sequence : 
| - Parse & Validate args (args-handlers, to create)
| - Build query (query-parsers : currently in gql-query-parsers, to
move)
| - Execute query
| - Fetch relation + format
#### Rest
- Simple parsing (without metadata validation)
- Calling Common API
- Simple rest response formatting
#### Gql
- Calling Common API
2025-10-08 10:18:42 +00:00
Charles BochetandGitHub 8914ba9fec Fix RelationToOneSection assignment bug (#14975)
While refactoring SingleRecordPicker to support morph use case, we
forgot to QA RelationDetailSection for ManyToOne.
2025-10-08 11:30:42 +02:00
19be7b0a7c Fix: missing settings tab due to YAML parsing (#14775)
The [settings
page](https://twenty.com/user-guide/section/settings/settings) doesn't
exist.

The settings.mdx had an info section with the value `Learn how to manage
your workspace: permissions...`.

The string contained a colon which caused YAML to misinterpret the
value. Added quotes to fix.
<img width="288" height="617" alt="image"
src="https://github.com/user-attachments/assets/ff012c8b-09af-4b9d-8dd8-05f2a5bbd48b"
/>

---------

Co-authored-by: Jason <jomarin002@gmail.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-08 10:12:14 +02:00
dd4cc98b8a Update Error Handling for 2FA Requirements in Impersonation (#14963)
# Fix 2FA Error Handling in Impersonation

**Related Task:** https://twill.ai/twentyhq/ENG/tasks/2

## Summary

This PR improves error handling for two-factor authentication (2FA)
requirements during user impersonation by enhancing the GraphQL error
utilities.

## Changes Made

- Enhanced GraphQL error handling utilities to properly manage 2FA
requirement errors
- Added improved error messaging and handling for impersonation
scenarios where 2FA is required

## Why This Change?

Fixes #14962 - Users were experiencing unclear error messages when
attempting impersonation without proper 2FA setup. This update ensures
more descriptive error handling and better user experience during the
impersonation flow.

Co-authored-by: Twill <agent@twill.ai>
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-07 22:45:20 +02:00
Charles BochetandGitHub 84f1559832 Refactor SingleRecordPicker to handle morphs (#14956)
## Scope

- Refactor SingleRecordPicker to handle morphItem and match Multiple one
- fix query generation to take morph into account


Left: 
- double check SingleRecordPicker in Workflows / Form
- Fix tests / stories
2025-10-07 20:07:27 +02:00
8829eb5a4a i18n - translations (#14957)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-07 18:48:19 +02:00
94546d7c09 Add composites subfield selection in the graph editor (#14931)
Closes https://github.com/twentyhq/core-team-issues/issues/1638
Closes https://github.com/twentyhq/core-team-issues/issues/1623



https://github.com/user-attachments/assets/2dddadaa-781b-497d-b454-0066d599bda3

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-10-07 18:33:07 +02:00
Baptiste DevessierandGitHub e382730a39 Accept any json value in result and error (#14954)
Some users might throw JS values that aren't strings.

<img width="3456" height="2160" alt="CleanShot 2025-10-07 at 17 48
36@2x"
src="https://github.com/user-attachments/assets/b02f886c-1c8e-4186-954b-6d0e025a6fcf"
/>

Errors seen previously:

<img width="1308" height="840" alt="image"
src="https://github.com/user-attachments/assets/1d7e4947-8f6f-44fb-aefb-c7d105712204"
/>
2025-10-07 18:25:51 +02:00
EtienneandGitHub f037e92dfa fix incorrect data in sample export (#14933)
fixes https://github.com/twentyhq/twenty/issues/14928
introduced by https://github.com/twentyhq/twenty/pull/14347
2025-10-07 16:20:33 +00:00
Baptiste DevessierandGitHub 94a1cfad83 Add Array Form Field (#14935)
https://github.com/user-attachments/assets/93c48584-8b6c-4e44-8161-1026d056b7bf
2025-10-07 18:12:26 +02:00
238f0c0ce2 i18n - translations (#14955)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-07 18:01:11 +02:00
MarieandGitHub 0474f00b5f [groupBy] Date ranges (#14923)
Closes https://github.com/twentyhq/core-team-issues/issues/1559

2 kinds of date ranges: absolute (day, month, quarter, year) and
"cyclic" (day of the year, month of the year, quarter of the year. ex
dates in january 2024 and january 2025 will be grouped together in
"Q1").

Absolute dates are expressed in datetime format to ease their handling,
while cyclic dates are expressed with more human readable labels ("Q1")
because datetime does not make sense anyway

<img width="851" height="722" alt="Capture d’écran 2025-10-06 à 18 13
29"
src="https://github.com/user-attachments/assets/44cce55d-a363-4bfa-a13d-e385ce5d227e"
/>

<img width="854" height="716" alt="Capture d’écran 2025-10-06 à 18 14
02"
src="https://github.com/user-attachments/assets/c1c1f176-c5b6-441c-b419-7e1692600b65"
/>

<img width="878" height="721" alt="Capture d’écran 2025-10-06 à 18 14
14"
src="https://github.com/user-attachments/assets/76318c53-e1cd-4e73-aa56-9e705ea40596"
/>
2025-10-07 15:52:24 +00:00
063db1efe2 i18n - translations (#14952)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-07 17:47:01 +02:00
0dcfa11893 i18n - translations (#14950)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-07 17:34:18 +02:00
f60817a1e1 Morph many to one picker (#14155)
This PR follows the multiSelect PR merged previously. It will enable
morph relation Many to One to be handled from the table, using a
singleSelect picker

Main point : I decided to change the singleSelect API to take an array
of **objectMetadataName** instead of only one to deal with both our
usecases.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-07 17:25:11 +02:00
9f9c2d85ca Feat/14419 added infinite scroll icon picker (#14792)
## 📝 Summary
Added **infinite scroll support** in the **IconPicker** dropdown by
extending `DropdownMenuItemsContainer` with an optional `onScroll`
handler.

Fixes #14419  

---

## 🔄 Changes
- Updated `DropdownMenuItemsContainer` to accept an optional `onScroll`
prop.
- Implemented lazy-loading of icons in `IconPicker` (loads 50 more icons
when the user scrolls).
- **Note**: Infinite scroll is **disabled** if a `maxIconsVisible` prop
is passed — in that case the list is static.
- No new UI elements were added

---
##  How it Works
- Scroll event is captured via `onScroll`.
- When the user scrolls near the bottom:
  ```ts
  target.scrollTop + target.clientHeight >= target.scrollHeight - 10

---

## Demo ->

[Screencast from 2025-09-30
20-47-03.webm](https://github.com/user-attachments/assets/d8906ebd-3cf1-4a89-a10d-a049b098c94f)



Attached screen recording of infinite scroll in action.

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-10-07 15:20:51 +00:00
WeikoandGitHub 9aaed28dcf Fix app deletion missing cache invalidation (#14944)
App deletion currently deletes all related entities through postgres
cascade delete meaning we never run actual migrations ourself and never
trigger cache invalidation (part of migration engine)
2025-10-07 16:57:22 +02:00
46955e2d99 i18n - translations (#14948)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-07 16:47:45 +02:00
9c8e0f628e Redirect to select option creation when no result (#14460)
fix:Ability to add a new option for a multi-select on the fly 
Issues:#13877

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-10-07 14:39:48 +00:00
2445668e96 i18n - translations (#14945)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-07 16:01:05 +02:00
Raphaël BosiandGitHub 22db1bb97d Updates on chart selection (#14943)
- Updated the disabled design
- Disabled the 3 charts which won't be released this sprint
- Updated the icon of the number chart
- Added labels

Before:
<img width="1004" height="388" alt="CleanShot 2025-10-07 at 15 40 31@2x"
src="https://github.com/user-attachments/assets/d2cf86a4-faca-4333-a03b-cc95afbd07ad"
/>

After:
<img width="1002" height="412" alt="CleanShot 2025-10-07 at 15 46 21@2x"
src="https://github.com/user-attachments/assets/780e9bcb-32d7-41dc-b281-f7b2248b8f5d"
/>
2025-10-07 13:55:52 +00:00
Antoine MoreauxGitHubCopilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
f8f113b82e Potential fix for code scanning alert no. 173: Uncontrolled data used in path expression (#14924)
Potential fix for
[https://github.com/twentyhq/twenty/security/code-scanning/173](https://github.com/twentyhq/twenty/security/code-scanning/173)

To fix this vulnerability, ensure that any file path constructed from
untrusted user input is strictly confined to the intended storage
directory. This is best done through path normalization and validation.
Before reading the file, the following steps should be taken:
1. **Resolve the file path**: Use `path.resolve` to normalize the
resulting path, removing any ".." segments or symbolic links.
2. **Check the parent directory**: Ensure that the resolved path starts
with the intended storage directory (`this.options.storagePath`).
3. **Throw an exception**: If the resolved path does not start with the
storage root, throw an exception or otherwise deny the operation.

This check should be placed in all methods that build a file path from
user input in `local.driver.ts`, with at least the `read` method
addressed. The index for this fix will be on lines that construct and
use `filePath`, specifically in the `read` method.

You will need to:
- Import `realpathSync` from `fs` (standard library).
- Add safe path resolution and containment check around file access.

---


_Suggested fixes powered by Copilot Autofix. Review carefully before
merging._

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-10-07 14:33:34 +02:00
f935dd44d7 i18n - translations (#14936)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-07 13:45:43 +02:00
Paul RastoinandGitHub 23e21cbeea Label identifier validation v2 (#14867)
# Introduction
Adding a hacky way to validate object against fields before fields
validation ( bi-directional validation process )
If you encounter an identical setup we will add a specific devXp as
cleanup validation but for the moment this seems enough

close https://github.com/twentyhq/core-team-issues/issues/1639
2025-10-07 13:27:21 +02:00
Abdul RahmanandGitHub 0670bb2043 Remove member default role from API key creation (#14932) 2025-10-07 11:48:24 +02:00
WeikoandGitHub 337f1a98a8 Fix auth + cli -V not picking up package json (#14934)
- Auth was failing, GQL query was not well formatted
- -V was not working as expected and was reading hardcoded version
instead of package.json
- CommanderError due to early exit (with -V for example) were thrown and
logged, now not logging those
2025-10-07 11:46:23 +02:00
Paul VerninandGitHub f0ad005f8f Make entire first cell clickable (#14925)
Solution: 
I removed the specific layout of the first cell that was reducing the
clickable area to make room for the “+” button.
Instead, I added a layout to the button, so it’s position absolute,
allowing the clickable area to cover 100% of the cell while keeping the
button above it.
Another possible solution would be to modify
`RecordTableColumnHeadWithDropdown` to include the button inside...

- Manual test:
[Loom](https://www.loom.com/share/4ceb4daa07e5457a99a07a2489db2960?sid=15959502-e272-44bd-923a-5764d077642d)
- Issue: https://github.com/twentyhq/twenty/issues/14900
2025-10-07 07:50:08 +02:00
Charles BochetandGitHub 0fd6085b53 Prevent querying too much on worklow index page (#14916)
## Performance short term fix

Done in this PR:
workflowVersions and workflowRuns are heavy object. I'm preventing
loading their data when they are loaded as relations. This will reduce
the work on backend

## Long term fix

Todo:
We should make sure workflow data is ligher
2025-10-06 23:53:58 +02:00
Antoine MoreauxandGitHub 5300ec5309 chore(ci): update GitHub Actions workflows for improved reliability a… (#14921)
…nd version handling
2025-10-06 22:13:45 +02:00
a3a25aaae5 Integrate IMAP and SMTP clients for message sending (#14688)
Implement functionality to send messages using both IMAP and SMTP
clients, allowing for message storage in the Sent folder.

Closes #14379

---------

Co-authored-by: neo773 <neo773@protonmail.com>
Co-authored-by: neo773 <62795688+neo773@users.noreply.github.com>
2025-10-06 18:41:18 +02:00
martmullandGitHub e54aa9d925 Fix rimraf not cleaning dist properly (#14903)
trying to solve build errors when launching commands

```console
> nx run twenty-shared:generateBarrels  [existing outputs match the cache, left as is]


> nx run twenty-shared:build  [existing outputs match the cache, left as is]


> nx run twenty-emails:build  [existing outputs match the cache, left as is]


> nx run twenty-server:typecheck

> tsc -b tsconfig.json --incremental


> nx run twenty-server:build

> rimraf dist

> nest build --path ./tsconfig.build.json


>  SWC  Running...
[Error: ENOTEMPTY: directory not empty, rmdir '/Users/martinmuller/Desktop/twenty/packages/twenty-server/dist/src/modules'] {
  errno: -66,
  code: 'ENOTEMPTY',
  syscall: 'rmdir',
  path: '/Users/martinmuller/Desktop/twenty/packages/twenty-server/dist/src/modules'
}
```
2025-10-06 18:32:55 +02:00
Antoine MoreauxandGitHub 93d55d1bc2 chore(workflows): update permissions across GitHub Actions workflows … (#14919)
…for consistency
2025-10-06 17:36:41 +02:00
Antoine MoreauxandGitHub 843689ee05 chore(twenty-website): upgrade next (#14917)
Standardized `PageProps` usage across multiple pages. Upgraded `next`,
`eslint-config-next`, and related dependencies to `^15.5.4` for
compatibility and performance improvements.
2025-10-06 15:08:16 +00:00
martmullandGitHub e40d5c9025 Update twenty-cli version before deploy (#14918)
Upgrade from 0.1.0 to 0.1.1
2025-10-06 16:48:48 +02:00
Antoine MoreauxandGitHub 695b4a2139 fix(cloudflare): cloudflare webhook (#14834) 2025-10-06 14:39:19 +00:00
Antoine MoreauxandGitHub bc2070410c chore(dependencies): remove unused dependencies from package.json and… (#14914)
… yarn.lock
2025-10-06 14:38:44 +00:00
Paul RastoinandGitHub b870ed238f Fix twenty-server integration test on main (#14905)
Following https://github.com/twentyhq/twenty/pull/14869

Dynamically clearing the cache, as one entry was forgotten
It seems like a permission test deletes a role that's expected to be
existing in following tests, as now cache is getting invalidated tests
are failing

Seems to be related to
https://discord.com/channels/1130383047699738754/1423768505911869460

## Singleton local cache key collision
When set for the first time caches local keys looks like
`workspaceId:undefined", singleton is shared between several cache
instances
If the given key is undefined it will read on other entity cache entry.
2025-10-06 13:51:48 +00:00
Antoine MoreauxandGitHub db7fe8b327 chore(dependencies): upgrade @nestjs/devtools-integration to v0.2.1… (#14912)
… and update peer dependencies
2025-10-06 15:14:57 +02:00
Antoine MoreauxandGitHub 143d5b8061 chore(dependencies): bump @node-saml/node-saml to 5.1.0 and `@node-… (#14911)
…saml/passport-saml` to ^5.1.0 in `yarn.lock` and `package.json`
2025-10-06 15:14:02 +02:00
Antoine MoreauxandGitHub 5623364c4b chore(dependencies): remove unused Monaco Editor packages (#14913) 2025-10-06 15:11:34 +02:00
Paul RastoinandGitHub 4290b30309 Update one object v1 invalidates field v2 cache (#14902) 2025-10-06 14:28:00 +02:00
EtienneandGitHub c1671c6ff6 fix server level impersonation (#14909) 2025-10-06 14:18:20 +02:00
6f4c12922b i18n - translations (#14910)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-06 14:01:17 +02:00
062fbe90ea Add 'Add a node' button to command menu for workflow node insertion (#14805)
Related issue: https://github.com/twentyhq/core-team-issues/issues/1585

## Summary

Added a new "Add a node" button to the command menu that enables users
to insert workflow nodes through the command interface. This enhancement
improves the workflow creation experience by providing an additional,
accessible way to add nodes to workflows.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-06 13:51:46 +02:00
6c4ae1ae33 Ability to navigate/scroll the workflow canvas with sliding two fingers (#14804)
**Issue**: https://github.com/twentyhq/core-team-issues/issues/1587

### Changes Made
- Modified scroll event handling to detect and limit two-finger scroll
gestures to the workflow canvas component
- Improved user experience by preventing accidental navigation or
zooming outside the intended canvas area

---------

Co-authored-by: Twill <agent@twill.ai>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-06 13:44:23 +02:00
Baptiste DevessierandGitHub 6b463736cc Handle empty values for boolean form field (#14884)
This PR uses a select component instead of `BooleanInput` for boolean
form fields. This makes it clear that the default value is `undefined`.

## Before


https://github.com/user-attachments/assets/84061638-0ba0-4f79-965e-90517d45aa3e

## After


https://github.com/user-attachments/assets/cdbcf935-5c5b-46d1-a1cc-110670b460ee

Fixes https://github.com/twentyhq/twenty/issues/14851
2025-10-06 11:57:55 +02:00
martmullandGitHub f6240fabd0 Fix hello world application (#14880)
Updates of the hello-world application
- remove the old hello-world application
- adds an object "postCard"
- adds a serverlessFunction `create-new-post-card` that calls the twenty
api to create a new postCard record
- add a route trigger /post-card/create?recipient=John
2025-10-06 10:51:33 +02:00
martmullandGitHub 31b73c3580 esBuild serverless (#14886)
Use [esbuild](https://esbuild.github.io/) to Build serverless entire
folder instead of just the src/index.ts file. Application serverless
folders can contain code organized in folders

## Small example

This now works:

<img width="1330" height="686" alt="image"
src="https://github.com/user-attachments/assets/e0639517-492d-4b64-8722-18bbe94dacb0"
/>
2025-10-06 10:47:42 +02:00
1a9bc6d3dd i18n - translations (#14898)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-06 09:20:57 +02:00
66d9a6d7bc Fix Admin control to disable workspace creation for non-admin users (#14895)
fix #13460

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-06 09:11:17 +02:00
Charles BochetandGitHub cd4800eb86 Fix exception handling on messaging + optimistic on object delete (#14894)
## What

In this PR, we are fixing two issues:
- while deleting an object, the views are not properly refreshed leading
to FE bug. This is due to the fact that we were refetching **views
associated to the object** which has been deleted. As views are properly
deleted in the BE, the FE gets no views from this call and cannot
optimistically react. In this case, I'm triggering a complete view
refetch
- messaging error handling had a hole
2025-10-04 20:19:26 +02:00
Félix MalfaitGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
888bf45422 Add new Agents (#14883)
Still experimenting

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-10-04 06:45:13 +02:00
Paul RastoinandGitHub d3a7241b6f Cache flush after database reset (#14873)
When starting the app on a fresh database reset the cache would be
filled with empty flat field metadata maps
Because the reset command hack through the repository directly in order
to create views and stuff
implemented an iso flush as the one existing initially
added it to a workspace deletion tambien
```
{
   byId: {],
   universalIdById: {}
}
```
2025-10-03 17:51:24 +02:00
Charles BochetandGitHub 81e9a02101 Increase chunk limit (#14881)
As per title
2025-10-03 17:32:21 +02:00
Charles BochetandGitHub c5cdf45f85 Improve performances (#14869)
## Improvements

- Add logs to all gql operations and rest calls to help debug CPU issues
on the backend. These are temporary and should be removed
- Remove nested relations from workflowVersions load (used to add manual
triggers in the side bar). On some workspaces this call result in a
response of 4MB which is heavy on CPU
- Investigated Redis Usage ==> made a few improvements, we are should
still migrate to the new cache service once available
- investigated db calls in messaging / calendar fetch list + workflow
enqueue run cron jobs. Everything seems to be properly batched
2025-10-03 17:22:03 +02:00
martmullandGitHub f973a1bcdb Publish twenty-cli npm package (#14871)
as title
2025-10-03 13:08:06 +00:00
0648dc5c65 Fix AI chat streaming persistence when command menu closes (#14854)
Closes [#1583](https://github.com/twentyhq/core-team-issues/issues/1583)


- Removed `messageId` column from `File` table and its references in
code (unrelated to this PR)
- Updated AI chat to use React Context API with persistent provider in
`CommandMenuContainer`
- Converted all AI chat component states to regular Recoil atoms (no
instance context needed)

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-03 12:37:41 +02:00
WeikoandGitHub 329af2b670 Add route trigger to twenty apps (#14864) 2025-10-03 12:11:18 +02:00
Paul RastoinandGitHub a6ffd4707a Dev seed ycombinator workspace is on v1 (#14868)
Tested v1:
- object CRUD
- FIELD CRUD
- VIEW CRUD
- VIEW FIELD CRUD
2025-10-03 10:01:00 +00:00
d0ff2d31a2 i18n - translations (#14866)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-03 10:35:40 +02:00
Raphaël BosiandGitHub d10ab5f67c Chart editor - Part 1 (#14820)
This PR is the first part of the creation of the Chart editor.


https://github.com/user-attachments/assets/8b0af8ea-be41-4506-84cb-e40f5521cbf0

Done:
- Bar chart settings (except filters)
- Line chart settings (except filters)

In progress:
- Pie chart settings
- Number chart settings
- Gauge chart settings

Left to do:
- Loosen the backend validation to allow the user to save a partial
configuration, validate the graph configuration in the frontend and
display a error friendly message in the graph if the config is not
completed yet
- Implement the filter edition
- Finish the other graph types settings
2025-10-03 10:25:45 +02:00
fc8b4f813c i18n - translations (#14863)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-03 00:32:40 +02:00
WeikoandGitHub 0b60aa4249 Add custom routes to migration v2 (#14846)
## Context
Add routes to migration V2
- Resolvers
- Service v2
- Builder
- Validator
- Action runner

Next PR: Add to twenty-cli to sync routes with serverless
2025-10-03 00:20:21 +02:00
Charles BochetandGitHub dcfae3821c Fix race condition user and views (#14861) 2025-10-02 23:46:47 +02:00
Thomas des FrancsandGitHub 14f2892b68 1.7 changelog (#14853) 2025-10-02 22:53:28 +02:00
Charles BochetandGitHub 5dcd0607b3 Fix performances on view loading (#14859)
## Context

We are experiencing bad performance on Twenty. One of the root cause
hypothesis is that computing `currentUser.currentWorkspace.views` is CPU
consuming. Without views, the GetCurrentUser response is ~1000 lines.
With its ~10000 lines.

As graphql is going through all fields recursively this can be quite
heavy on CPU. We had a similar issues on ObjectMetadataItems 2 years ago
and came with storing the response in redis.

Note: I thought there was also a cache in RAM but this is not the case,
so to invalidate the cache we can just empty redis.

## How

- Extract getting all views from GetCurrentUser and update frontend to
perform both queries
- Add views to cached graphql operations
- invalidate the cache manually on view or related core entities update
/ create / delete / destroy

## Tests

I have tested a lot on v1
2025-10-02 22:53:03 +02:00
martmullandGitHub 87256e82f5 Improve readme (#14858) 2025-10-02 22:50:37 +02:00
d4160bf064 feat(redis): add support for dedicated queue client configuration (#14840)
Fix https://github.com/twentyhq/core-team-issues/issues/452
Fix https://github.com/twentyhq/core-team-issues/issues/923

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-02 19:14:12 +02:00
d2fad6754d i18n - translations (#14855)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-02 18:48:05 +02:00
Félix MalfaitandGitHub d4914aa130 Fix workspace logo, cookie security, and improve workspace impersonation (#14838)
3 small fixes:
- Fix workspace logo
- Improve cookie security
- Improve workspace impersonation
2025-10-02 18:36:52 +02:00
EtienneandGitHub 388e49a8cf fix impersonation guard on admin panel user lookup (#14845)
Mistakenly remove ImpersonateGuard on userLookupAdminPanel resolver ([cf
here](https://github.com/twentyhq/twenty/pull/14360/files#diff-01404fa6bc9b1350a87050b747889b299dc2deda50a62fe9b99327be3250bf96R49))
+ Add AdminPanelGuard

Re-create the previous ImpersonateGuard and add it to the resolver +
Remove the AdminPanelGuard
2025-10-02 16:35:58 +00:00
218c9d82f2 i18n - translations (#14850)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-02 18:21:23 +02:00
Paul RastoinandGitHub 170f6d27c5 Extract field metadata build out of object metadata build (#14763)
# Introduction

Extracting the legacy fields build and dispatch out of the object one to
follow the generic flat entity build, also update caches entries for
object

## Main tasks
- flat field map cache
- flat field builder
- refactored the dispatch matrix to return flat entity maps instead of
flat entity arrays
- orchestrator aggregator
- removing legacy code
- making universal identifier aka standardId of standard field for
custom object deterministically dynamic
- perfs debug logs for v2

## TODO
- [x] Refactor the generic entity builder to be dependency flat maps in
order to main foreign keys list in flat parent
- [x] Refactor the flat object metadata to contain the array of related
fields and avoid costy find object fields
- [ ] Improve the create field handler to handle multiple field at once
- [ ] Refactor the dispatch to embbed the comparison
- [ ] Improve perf by extracting from elements out of existing
- [ ] Fix the labelIdentifierId validators on object before field
creation ( integ tests are in failing mode )

## Debug logs snippet

```ts
[EntityBuilder fieldMetadata] matrix computation: 0.027ms
[EntityBuilder fieldMetadata] creation validation: 0.001ms
[EntityBuilder fieldMetadata] deletion validation: 0.293ms
[EntityBuilder fieldMetadata] update validation: 0.006ms
[EntityBuilder fieldMetadata] entity processing: 0.363ms
[EntityBuilder fieldMetadata] validateAndBuild: 0.455ms
[EntityBuilder index] matrix computation: 0.005ms
[EntityBuilder index] creation validation: 0.001ms
[EntityBuilder index] deletion validation: 0.146ms
[EntityBuilder index] update validation: 0.004ms
[EntityBuilder index] entity processing: 0.199ms
[EntityBuilder index] validateAndBuild: 0.228ms
[Runner] Initial cache retrieval: 0.549ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_index executeForWorkspaceSchema: 11.665ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_index executeForMetadata: 12.864ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForWorkspaceSchema: 1.476ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForMetadata: 6.816ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForWorkspaceSchema: 0.062ms
[BaseWorkspaceMigrationRunnerActionHandlerService] delete_field executeForMetadata: 0.889ms
[Runner] Transaction execution: 23.434ms
[Runner] Cache invalidation: 316.662ms
[Runner] Total execution: 340.767ms
```
As you can see cache invalidation is way to long, we could replace the
cache by the optimistic in the end
2025-10-02 16:07:34 +00:00
Raphaël BosiandGitHub d4b83df3f5 Fix menu item overflowing hiding icon buttons (#14847)
FIxes https://github.com/twentyhq/twenty/issues/14764

<img width="3944" height="886" alt="CleanShot 2025-10-02 at 16 01 43@2x"
src="https://github.com/user-attachments/assets/9d6cbb73-903d-4fd1-9456-395aa9745c45"
/>

<img width="525" height="1266" alt="CleanShot 2025-10-02 at 16 06 34@2x"
src="https://github.com/user-attachments/assets/cc6d6e89-48f7-48da-abff-b8458c2e7ae3"
/>
2025-10-02 16:35:28 +02:00
Félix MalfaitandGitHub 4a4777ef78 Enforce 2FA for server-level impersonation (#14842)
Better for security
2025-10-02 16:20:36 +02:00
4d8b68cf4d Hacktoberfest 2025 Banner (#14843)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-02 16:17:55 +02:00
MarieandGitHub 8b2447a624 [Fix] Cannot remove any field filter (#14813)
Fixes https://github.com/twentyhq/twenty/issues/14766

To reproduce
1. create a view with a any field filter and save it. After, remove any
field filter clicking on the X on the chip. No "Update view" shows.
2. now add another regular filter to the view and save it. Now remove
any field filter clicking on the X on the chip and remove the regular
filter you just added. Now "Update view" shows, click it and refresh the
page. Any field filter still shows

There were two problems
1. UpdateViewButtonGroup is in charge of showing "Update View" button.
But is never mounted if shouldExpandViewBar is falsy.
shouldExpandViewBar was not considering
viewAnyFieldFilterDifferentFromCurrentAnyFieldFilter so even if any
field filter had changed, UpdateViewButtonGroup still wasn't going to
show "Update view" button because it wasn't mounted
2. At save time, we added anyFieldFilterValue to the mutation payload if
 ```
...(view.anyFieldFilterValue && {
      anyFieldFilterValue: view.anyFieldFilterValue,
    }),
    ```,
but in JS an empty string evaluates to falsy.
2025-10-02 14:14:51 +00:00
MarieandGitHub 98544a2479 [Fix] Handle deprecated viewFilterOperand - follow-up (#14841) 2025-10-02 13:16:42 +00:00
Ketan MehtaandGitHub 2f5cd0df6b fixed convertUpdateViewInputToCore for zero value (#14754)
fix #14745
2025-10-02 13:13:13 +00:00
martmullandGitHub 96aa4cd6a4 Fix typo (#14839)
as title
2025-10-02 14:25:34 +02:00
martmullandGitHub 0368d2a094 1574 extensibility twenty cli use workspace migration v2 to synchronize serverless function triggers (#14830)
twenty-cli serverless triggers follow up. Fixes:
- eventName don't support wildcard
- universalIdentifier not used to create or update trigger : update does
not work properly (does deletion then creation)
- add a base project in twenty-cli that is copied when creating a new
app
2025-10-02 14:06:56 +02:00
Antoine MoreauxandGitHub 326d2a99ed fix(integration-tests): add generateUniqString for tests (#14832) 2025-10-02 13:46:49 +02:00
MarieandGitHub aac1314f5b [Fix] Handle deprecated viewFilterOperand in workflows run & on interface (#14837)
In this PR https://github.com/twentyhq/twenty/pull/14785 we deprecated
viewFilterOperand (from camelCase to capital snakeCase values), but we
had not migrated the existing workflow steps values. Hence they cannot
be executed!

Let's fix that by dealing with both operands, new and deprecated, to
mitigate the issue. Then we will add a command to migrate the values.
2025-10-02 13:08:24 +02:00
Abdul MateenandGitHub 8098391c21 Refactor Makefile for streamlined service definitions (#14757)
Streamline service definitions in the Makefile by ensuring the
`ensure-docker-network` dependency is called directly in each service
target instead of manual invocation. This change simplifies the process
of creating Docker services.

Closes #14715
2025-10-02 11:55:05 +02:00
WeikoandGitHub c2d45842a4 Add calendar view to feature lab (#14835) 2025-10-02 11:19:48 +02:00
Thomas TrompetteandGitHub 3fa12bb9fc Search record schema migration breaks following workflow steps (#14833)
If iterator loop feature flag is not enabled, `all` field in undefined
in search record schema. We need to handle that case properly.
2025-10-02 11:04:38 +02:00
EtienneandGitHub 7b16796a20 Fix server level impersonation (#14831)
Tested : 
- server level ok
- workspace level ok
- server level without canImpersonate or without allow impersonation -
fail ok
- workspace level without permission - fail ok
2025-10-02 10:46:59 +02:00
WeikoandGitHub 3f9c315d93 Add triggers to cli sync (#14828) 2025-10-02 02:08:38 +02:00
martmullandGitHub 6fdd7894a1 Add serverless function in twenty-cli (#14819)
- add serverlessFunction schema in twenty-cli
- add trigger schema in twenty-cli
- update serverless function code save and get
- sync serverless function
2025-10-01 22:11:03 +02:00
WeikoandGitHub 64dc726f50 rename application standardId to universalIdentifier (#14825)
## Context
Rename standardId in application table to universalIdentifier to align
with the rest of migration v2 guidelines
2025-10-01 20:20:20 +02:00
Charles BochetandGitHub ec317bd3d0 Fix workflow upgrade command (#14824)
While upgrading to 1.7.0, we are facing an error in the workflow version
upgrade for outdated workflow versions. Fixing the command
2025-10-01 19:57:43 +02:00
9c4d9298f8 i18n - translations (#14822)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-01 18:48:18 +02:00
Abdul RahmanandGitHub 20403664e3 Feat: native model capabilities (#14787) 2025-10-01 18:37:21 +02:00
WeikoandGitHub d715533a90 Fix path retrieval for twenty apps in twenty-cli (#14818)
## Context

Now should not confuse package.json from non-twenty apps but check if
$schema correctly targets twenty manifest json
<img width="741" height="422" alt="Screenshot 2025-10-01 at 17 34 45"
src="https://github.com/user-attachments/assets/5b9e729e-8634-4eb8-a2a9-4991a63d49f0"
/>
2025-10-01 18:11:42 +02:00
GuillimandGitHub bb0d37d79f add the contextual text for multiselectavatar and selectavatar (#14807)
necessary for the new design from @bonapara in Figma here
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=70184-191735&t=s5CaYKWjRp64ECkN-11

Should look like this
<img width="397" height="416" alt="Screenshot 2025-10-01 at 11 25 00"
src="https://github.com/user-attachments/assets/fe585d34-f9b9-438a-91e2-8177722cc922"
/>

As you can see in the storybook, it looks like this :
<img width="681" height="414" alt="Screenshot 2025-10-01 at 11 25 25"
src="https://github.com/user-attachments/assets/8fa1b99c-9eb0-4f1e-a0a2-4ad136f977cc"
/>


Tech:
I took the same wording as "contextualText" as defined in the other
select component but decided to stay string only since I did not want to
overcomplicate the API for now. In that, it slightly differs from the
other components designed by @bosiraphael a week ago I think
2025-10-01 16:42:48 +02:00
WeikoandGitHub 1b985ed5b1 Fix calendar padding and set calendar top bar fixed (#14815) 2025-10-01 16:31:41 +02:00
Thomas TrompetteandGitHub e945c83bbe Add workflow iterator to lab (#14814)
As title
2025-10-01 15:31:40 +02:00
ae4a93c993 feat: add create or update workflow trigger (#14708)
### Description

This PR focuses on
https://github.com/twentyhq/core-team-issues/issues/1476

- introduces the handling of upserted events in the workflow trigger
system


## Visual Appearance
<img width="1792" height="1039" alt="Screenshot 2025-09-21 at 11 40
28 PM"
src="https://github.com/user-attachments/assets/d926b566-f7d3-412b-b1ab-ed2064425f3d"
/>

<img width="501" height="1025" alt="Screenshot 2025-09-21 at 11 40
39 PM"
src="https://github.com/user-attachments/assets/13c3031a-0762-4c80-8df1-fa74ca70a540"
/>


### Changes
- Added `UPSERTED` action to the `DatabaseEventAction` enum.
- Updated the `WorkflowEditTriggerDatabaseEventForm` to support upserted
events.

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-10-01 15:17:05 +02:00
Antoine MoreauxandGitHub b5e6703f35 refactor(captcha): add path-based captcha check and cleanup unused to… (#14803)
…ken requests
2025-10-01 15:15:40 +02:00
359036d9bc i18n - translations (#14812)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-01 15:01:05 +02:00
neo773andGitHub 62a1de221b Message Folders Redesign and Import Policy (#14714) 2025-10-01 14:48:46 +02:00
Baptiste DevessierandGitHub a68aa303aa Hide iteration switcher for steps following iterators (#14810)
## Before


https://github.com/user-attachments/assets/a8eca1aa-b2b6-4fdb-8848-65c8235a330c

## After


https://github.com/user-attachments/assets/84b7e969-423b-4f0e-8f53-524bfb11e2ca
2025-10-01 14:44:11 +02:00
Thomas TrompetteandGitHub f302b7c74e Put checkbox and tag into left content (#14811)
As title
2025-10-01 12:20:38 +00:00
Baptiste DevessierandGitHub b3153535a6 Fix step output for iterators (#14796)
It also prevents the app from crashing when opening the output of the
trigger node.

## Before

<img width="3738" height="2442" alt="CleanShot 2025-09-30 at 19 44
39@2x"
src="https://github.com/user-attachments/assets/39fa81b1-2c25-402e-9030-770054870f70"
/>

## After


https://github.com/user-attachments/assets/b7585690-dd3b-4875-9c3e-18b60b3acc3d
2025-10-01 14:15:07 +02:00
martmullandGitHub bc37a3a9bb Remove deprecated check (#14809)
as title
Thanks @Devessier for the report
2025-10-01 10:24:37 +00:00
346da2b2f2 i18n - translations (#14808)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-10-01 11:33:53 +02:00
Abdul RahmanandGitHub 3e61f91635 Structured agent chat messages follow up (#14797)
This PR addresses code review feedback from
[#14749](https://github.com/twentyhq/twenty/pull/14749)
2025-10-01 11:24:58 +02:00
Abdul RahmanandGitHub 9d7c36e92f Fix AI Chat permission error for users with restricted field access (#14799)
Closes [#1582](https://github.com/twentyhq/core-team-issues/issues/1582)
2025-10-01 11:21:16 +02:00
nitinandGitHub 4eaf87341f fix - lint main (#14802) 2025-10-01 07:05:56 +00:00
Antoine MoreauxandGitHub 1184c59c94 fix(billing): refactor and update subscription phase handling logic (#14783) 2025-09-30 23:25:21 +02:00
3c0a197525 Feat/add add icon to calendar view (#14696)
# Calendar View: Add "+" Button to Calendar Day Cards

## Description
This PR implements the "+" button on calendar day cards in the Month
view, allowing users to create new records directly from the calendar.

- The "+" button appears **on hover** only.  
- Newly created records include the **day representing the card** in the
payload (UTC, with only the date part).
- Respects **object permissions** and **soft delete filters**.  
- Automatically integrates with **active filters** used in Table and
Kanban views.

## Implementation Notes
- `RecordCalendarAddNew` component handles button visibility and record
creation.
- UTC date is passed to the create function to ensure proper timezone
handling.
- No unit tests added yet (need senior guidance).  

---
[Screencast from 2025-09-24
20-10-18.webm](https://github.com/user-attachments/assets/bd117b43-6c1b-4267-874f-b36844733d9e)

###  Video ->



## Related Issues
Fixes: https://github.com/twentyhq/core-team-issues/issues/1552

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-09-30 20:04:47 +02:00
Thomas TrompetteandGitHub 1c572294f9 Display actions on calendar item selection (#14795)
https://github.com/user-attachments/assets/e76a1de7-d6c6-45f2-8c2e-73beaf2eb6bf

Fix https://github.com/twentyhq/core-team-issues/issues/1553
Fix https://github.com/twentyhq/core-team-issues/issues/1554
2025-09-30 19:13:12 +02:00
WeikoandGitHub 0959b86f98 fix view update in migration v2 (#14794)
Legacy from early v2 implementation, we don't want to store relation ids
in the cache as the new implementation handle that with flat entities
properly already.

This causes some issues because when we return the updated view, it
contains an array of viewField objects with only the id in it so gql
complains because some fields are non-nullable in the output and the
resolver can't resolve viewField directly because viewField is in the
output (not complete though) already so it just ignores it.
2025-09-30 19:07:12 +02:00
8b2e43c448 Added all the initial selection logic (#14789)
Added initial implementation of calendar card selection logic 

---

Video -> 
[Screencast from 2025-09-30
19-50-56.webm](https://github.com/user-attachments/assets/757e5dbe-9936-4633-9178-d42a20401b82)

---
@Weiko

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-09-30 16:48:49 +00:00
MarieandGitHub f33396e425 [GroupBy] Add views filters to groupBy query 2/2: handle anyFieldFilter (#14791)
Following https://github.com/twentyhq/twenty/pull/14762 

In this PR
- moved logic around any field filter formatting to twenty-shared
- added any field filter to the filters applied to groupBy when viewId
is defined
- added integration test
2025-09-30 16:13:40 +00:00
MarieandGitHub 3927b36406 [View migration] Clean ViewFilterOperand (#14785)
In the BE we have stored filter operand as IS_EMPTY, IS_NOT_EMPTY, etc. 
For some reason in the FE we were manipulating IsEmpty, IsNotEmpty, etc.
(maybe because they were used before in Views before they were moved to
core)

So we were converting the operands in the FE from IS to Is
(convertViewFilterOperandFromCore) to read and manipulate viewFilters,
and then back to BE version to send mutations etc., from Is to IS
(convertViewFilterOperandToCore).
The migration is now over, so we can remove and simplify that code. 
(In the 1-5:migrate-views-to-core command we still do the migration from
Is format to IS format.)
2025-09-30 17:12:03 +02:00
Baptiste DevessierandGitHub 15975a2cfc Visualize workflow run step input (#14784)
https://github.com/user-attachments/assets/8358a252-0407-4925-a923-7b1d6c7404b0
2025-09-30 17:09:57 +02:00
martmullandGitHub 1938202780 1573 extensibility twenty cli handle custom layers for serverless functions of applications (#14779)
- allow specific layers for serverless functions
- add a serverlessFunctionLayer table
- sync application layer
2025-09-30 16:47:49 +02:00
5560d823c3 i18n - translations (#14788)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-30 16:20:36 +02:00
nitinandGitHub 274f4333b4 Field level permission checks on widgets (#14774) 2025-09-30 16:00:09 +02:00
Thomas TrompetteandGitHub c3b1f6c2b2 Store last iterator execution in history (#14786)
When all items have been processed, iterator should:
- store last iteration in history
- return the final result saying iteration have been successful. So it
gets stored by the executor

It was not doing the first step, so we were losing the last iteration.
Splitting into separated function + adding tests
2025-09-30 14:52:21 +02:00
MarieandGitHub 9bf633e9c9 Intercept all abortErrors (#14780)
Fixes https://github.com/twentyhq/twenty/issues/14569

Some extensions, such as SimilarWeb, are incompatible with twenty: they
trigger intempestive "AbortErrors" converted into error snackbar. While
twenty remains usable it is very annoying.

I did not take time to deeply investigate which requests are
problematic. According to ClaudeAI it may be because twenty makes a lot
of queries to the same endpoint /graphql, a pattern that SimilarWeb may
interpret as tracking which they try to intercept.

In this PR, we finish the work started in [this
PR](https://github.com/twentyhq/twenty/pull/13080) to silent harmless
AbortErrors.
2025-09-30 14:04:11 +02:00
Thomas TrompetteandGitHub b7cdf9183a Search record action - allow to search more than 1 record (#14769)
https://github.com/user-attachments/assets/426da6af-6c6b-4d49-9034-0aa041cb331f
2025-09-30 12:07:25 +02:00
nitinandGitHub 4b87908752 [Dashboards]- Addition of tabs (#14756) 2025-09-30 11:23:52 +02:00
ef988aa6cb i18n - translations (#14782)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-30 11:20:58 +02:00
WeikoandGitHub 68b21d2942 Add db event trigger and cron trigger to migration v2 (#14772)
## Context
Add DB events triggers and Cron triggers to migration v2 builder/runner
(and adding corresponding services/resolvers)
2025-09-30 11:14:18 +02:00
Thomas TrompetteandGitHub 123202df41 Store history for iterator (#14771)
As title
2025-09-30 10:32:40 +02:00
bbe2733bc0 i18n - translations (#14778)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-30 10:21:58 +02:00
+4 7692fb2b6c chore(billing): add tests + fix meter name for trial (#14701)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Righteousness Akinbola <righteousnessakinbola@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: Abdullah. <125115953+mabdullahabaid@users.noreply.github.com>
Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
2025-09-30 10:01:51 +02:00
MarieandGitHub da3c3d2b9d [GroupBy] Add views filters to groupBy query (#14762)
Closes https://github.com/twentyhq/core-team-issues/issues/1560

If viewId is defined in a groupBy query, we want to apply all filters of
the view to the query.
This required to move a lot of code from twenty-front to twenty-shared
to convert the filters as stored in the db into graphql filters,
applying the right combinations between filters etc., which was
previously only done in the FE.

This PR does not handle any field filters, it will be done in a later pr
2025-09-30 09:58:55 +02:00
80fa4c6c26 i18n - translations (#14770)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-29 17:20:50 +02:00
EtienneandGitHub b74ed36ce3 Add impersonate banner (#14734)
Related to https://github.com/twentyhq/twenty/pull/14360

<img width="1511" height="468" alt="Screenshot 2025-09-26 at 12 16 46"
src="https://github.com/user-attachments/assets/33e0e0b5-1226-455d-90f2-e4fc3deef7a8"
/>

@Bonapara, let you tell me if wording and banner color are ok. This
banner is displayed when a user is impersonating an other user
2025-09-29 17:10:46 +02:00
462e2015b1 i18n - translations (#14768)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-29 15:48:01 +02:00
Thomas TrompetteandGitHub 4329501743 Workflow run over a list of records + backfill availability on manual triggers (#14761)
- Allow to run workflow on a list of records
- Use new availability in manual trigger when iterator feature flag is
enabled
- Build a command to backfill availability in workflow trigger



https://github.com/user-attachments/assets/d685c01f-4059-4647-92a1-f5f529b560cf
2025-09-29 13:45:51 +00:00
59be3aab19 feat: Add ability to drag arrow tip to another node (#14657)
Allow users to drag the target of edges when editing workflows.

---------

Co-authored-by: Devessier <baptiste@devessier.fr>
2025-09-29 15:41:41 +02:00
Baptiste DevessierandGitHub 9b88cee1ce Visualize iterator sub step's output by iteration index (#14747)
## Demo


https://github.com/user-attachments/assets/27afff85-4f33-4e91-b28a-3dc868bb9ad7

## With several sub steps

> [!NOTE]
> Please note that as I created the component state, the iteration index
will be different for every step of a workflow run. We might have one
component state instance per iterator node. We can implement it in
another PR if we think it's the way to go.


https://github.com/user-attachments/assets/6b8cd06d-9051-474d-b438-dd6155cc3810
2025-09-29 15:40:42 +02:00
Thomas TrompetteandGitHub 358ab54690 Fix workflow menu icons (#14767)
As title
2025-09-29 12:00:05 +00:00
4f24fc403b i18n - translations (#14765)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-29 13:45:36 +02:00
nitinandGitHub ea144c434b Add configuration types for widgets (#14717)
closes https://github.com/twentyhq/core-team-issues/issues/1532
2025-09-29 11:41:26 +00:00
2685f4a5b9 Restructure agent chat messages with parts-based architecture (#14749)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-29 13:31:55 +02:00
84cbd8e092 i18n - translations (#14744)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-26 16:20:13 +02:00
Paul RastoinandGitHub 4fbdfb6abc Activate v2 default seed (#14660)
## Introduction
After enabling flag by default got following errors:
```ts
Test Suites: 48 failed, 1 skipped, 97 passed, 145 of 146 total
Tests:       499 failed, 1 skipped, 644 passed, 1144 total
Snapshots:   61 failed, 133 passed, 194 total
Time:        363.226 s
Ran all test suites.
```

## From
<img width="2952" height="1510" alt="image"
src="https://github.com/user-attachments/assets/7e3b20c6-2552-40a7-90bb-2d7b3002c895"
/>

## To
<img width="3134" height="1510" alt="image"
src="https://github.com/user-attachments/assets/4fc9ada4-3c14-4333-a1db-11daf87db8d6"
/>

There's a huge test bundle in the latest shard that we could split up

## Notes
- Set as failing morph relation field rename as for the moment we do not
handle relation field mutation
- fixed the object update and creation validation adding label
identifier field metadata id checks
- and more

Some integrations tests are still on the v1 ( they have before and after
all disabling and re-enabling the flat ) but mainly we now have more
coverage on the v2 than the v1.
Mainly related records, uniqueness have to be migrated the v2 and so
tests too
2025-09-26 16:05:09 +02:00
Thomas TrompetteandGitHub ead351cb9e Fix variable search for iterators (#14742)
Add specific search util for iterators. Also making workflow version id
optional in compute step output schema endpoint to avoid breaking
changes on next release.

Before


https://github.com/user-attachments/assets/2ceb5b38-4c0a-4d38-8f57-0e4467dcfd93

After


https://github.com/user-attachments/assets/3ce503ac-5299-4bca-906f-e0fef379df7c
2025-09-26 13:42:40 +00:00
9cd0025aed i18n - translations (#14739)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-26 14:22:53 +02:00
Thomas TrompetteandGitHub 2c34e1fb8a Allow bulk records for manual trigger (#14725)
https://github.com/user-attachments/assets/d6c565eb-9a29-4830-9396-5f979c8caa7b

- Added a new component for manual trigger (mostly duplicated from
previous one). Will remove the old one once all data are migrated
- Updated schema output so the current item of the iterator can be typed

Todo left:
- migrate old triggers
- add an util to search iterator output. Today current item fields will
be displayed as not found
- set new manual triggers for workflow runs
2025-09-26 14:17:40 +02:00
WeikoandGitHub 584389e17f add code checksum to flat serverless function (#14721)
## Context
Now adding serverless code sync within the migration v2 logic itself. To
do that we need to follow the
- Prepare flat input
- Build migration
- Run migration
steps where now the serverless function entity will store in DB and
cache a checksum of its code and the flat input will contain the code
with the checksum. Build will compare checksum and create an update
action containing the code if it has changed and the migration will now
run the corresponding services (instead of calling those in the parent
serverless service exposed in the API) allowing us to keep that logic
functional for other use cases such as import/export, twenty-cli and
twenty upgrades.
2025-09-26 10:24:36 +02:00
Abdullah.andGitHub 5a56d73fb2 Enables phone number search in the global search (Command Menu) for person records. (#14636)
## Changes Made

- Added phone fields to search indexing: Extended searchable field types
to include `FieldMetadataType.PHONES`
- Updated person entity search configuration: Added `phones` to the
fields indexed for person records
- Enhanced search format support: Phone numbers are now indexed in
multiple formats:
  - Raw number: `2071234567`
  - International with plus: `+442071234567`
  - International without plus: `442071234567`
- Optimized for phone data: Removed unnecessary text processing (e.g.
unaccenting) for numeric phone fields
- Created workspace migration: New command to regenerate search vectors
for existing workspaces

## Technical Details

The implementation modifies PostgreSQL `tsvector` generation to index
both `primaryPhoneNumber` and `primaryPhoneCallingCode` fields,
combining them into international formats. This enables users to search
phone numbers using the formats they naturally type.

### Modified Files

- `is-searchable-field.util.ts` – Added `PHONES` to searchable types
- `person.workspace-entity.ts` – Included `phones` in person search
fields
- `get-ts-vector-column-expression.util.ts` – Enhanced expression
generation to support multiple phone number formats
- `is-searchable-subfield.util.ts` – Added subfield filtering logic for
phone fields

## Testing

- **Unit tests**: Validated `tsvector` expression generation and
phone-specific logic
- **Integration tests**: Covered phone search scenarios across multiple
formats

## Migration

Includes the `upgrade:1-7:regenerate-person-search-vector-with-phones`
command, which safely updates existing workspaces by dropping and
recreating search vectors with phone indexing support.

## Note

Frontend and Backend are both storing normalized phone numbers, as they
should. The issue turned out to be with the seed file instead, which
contained outdated records.

I relied on the database as the source of truth without testing via the
creation of a new record and it was an incorrect evaluation on my part.
Note taken, I will be more comprehensive with my analysis from here on
since I now understand I must check comprehensively before reaching a
conclusion.
2025-09-25 20:18:49 +02:00
Raphaël BosiandGitHub 1fdfac4f0d Update menu items across the app (#14724)
Closes https://github.com/twentyhq/core-team-issues/issues/1568


https://github.com/user-attachments/assets/a0fe6538-8405-4b52-a6ce-7afa846ee5f3
2025-09-25 18:14:32 +02:00
martmullandGitHub 9b3e2bfb45 1571 extensibility twenty cli add command to create base entities like object agent or serverless (#14722)
Remove default agent when init new app

add command to create a new entity (object or agent)



https://github.com/user-attachments/assets/b8f28281-2b40-4eaa-a958-55d2dd5183c8
2025-09-25 16:43:26 +02:00
1d743359ba i18n - translations (#14718)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-25 14:23:01 +02:00
WeikoandGitHub 188d66909d Add ServerlessFunction to migration v2 (#14698) 2025-09-25 14:05:01 +02:00
martmullandGitHub edb331d68b 1541 extensibility twenty cli use workspace migration v2 to synchronize application objects fields views (#14706)
- synchronize objects


https://github.com/user-attachments/assets/257317bc-2881-4b98-a3d4-6ae52bd72aa0
2025-09-25 11:22:11 +02:00
Charles BochetandGitHub 71216b4db8 Add logs to debug worker performance on production (#14712)
As per title, just adding worker job execution time
2025-09-25 10:38:42 +02:00
7c6405cf5f docs: update PostgreSQL installation instructions for macOS (#14710)
This pull request improves the local development setup instructions for
PostgreSQL on macOS, especially for users installing via Homebrew. It
clarifies how to ensure the PostgreSQL server is running and addresses
potential issues with the default user role.
This pull request solves issue #14637 
I personally faced this issues today while trying to setup the project
on my M1 Macbook Air.

PostgreSQL setup enhancements:

* Added instructions to start the PostgreSQL service using Homebrew and
verify its status with `brew services list`.
* Provided guidance on checking for the existence of the `postgres` role
and steps to manually create it if missing, to avoid permission issues
during development.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-09-25 10:38:24 +02:00
nitinandGitHub 904be95148 Fix calendar booking step in onboarding when env var is not configured (#14707)
## The Issue

When CALENDAR_BOOKING_PAGE_ID env variable is not configured, the
onboarding flow still sets the booking step as pending in the database.
This causes users to get stuck on a broken booking page after
logout/login, as the Cal.com iframe tries to load with an empty calendar
link.

 ## The Fix

Made the booking step handling idempotent across the stack:

  Backend:
- setOnboardingBookOnboardingPending now checks if calendar is actually
configured before setting the step as pending
- getOnboardingStatus auto-cleans invalid booking states when detected
(booking pending but no calendar configured)
  - Empty strings in env are now treated as undefined in client config

  Frontend:
- Added navigation protection to redirect away from booking pages when
calendar isn't configured
- Existing defensive logic in useSetNextOnboardingStatus already skips
booking when no calendar ID

  Result

  - New users won't get invalid booking states
  - Existing bad data self-heals when users interact with the system
  - Backend and frontend stay in sync about when booking should be shown

Fixes the issue Felix reported where users saw a broken booking page in
production.
  
I think we should keep the old CAL_LINK constant for now - while we
could remove the booking onboarding step entirely, it would break the
plan/pricing modal which uses it as a fallback when no calendar is
configured. Open for discussion! -- May be we dont show the `Book a
Call` button if the env is not set -- but we should keep it as it is if
we want two different behaviors :)
  
  closes https://github.com/twentyhq/core-team-issues/issues/1558
2025-09-25 10:19:09 +02:00
neo773andGitHub 9286ffb88d batched updates/insert and delete invalid folders (#14702) 2025-09-25 10:14:03 +02:00
705c09e83b i18n - translations (#14704)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-24 20:01:20 +02:00
2af20a4cf0 Add UTC timezone label to CRON trigger form (#14674)
- Added 'Cron will be triggered at UTC time' notice below trigger
interval dropdown
- Positioned correctly between dropdown and expression field to match
design
- Only shows when Custom CRON option is selected

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-09-24 19:45:56 +02:00
Raphaël BosiandGitHub 37ce5c48bb Fix flaky test on page layout widget (#14703)
The flakiness was due to the test considering that the widgets were
ordered when they were not.
2025-09-24 17:08:24 +00:00
EtienneandGitHub 950ce44341 Import - Fix erase on update on Number, Boolean and Multi Select fields (#14686)
Before on an object with Number, Boolean, Multi-Select fields -->
createMany input from import feature with only one name firstName column
matched :

```
{
  "data": [
    {
      "booleanField": false,
      "createdBy": {
        "source": "IMPORT",
        "context": {}
      },
      "name": {
        "firstName": "Test"
      },
      "multiSelectField": [],
      "numberField": null
    },
    {
      "booleanField": false,
      "createdBy": {
        "source": "IMPORT",
        "context": {}
      },
      "name": {
        "firstName": "Test1"
      },
      "multiSelectField": [],
      "numberField": null
    }
  ],
  "upsert": true
}
```

After with same object : 


```
{
  "data": [
    {
      "createdBy": {
        "source": "IMPORT",
        "context": {}
      },
      "name": {
        "firstName": "Test"
      }
    },
    {
      "createdBy": {
        "source": "IMPORT",
        "context": {}
      },
      "name": {
        "firstName": "Test1"
      }
    }
  ],
  "upsert": true
}
```

Fixes https://github.com/twentyhq/twenty/issues/14672
2025-09-24 18:38:42 +02:00
3cada58908 Migrate from Zod v3 to v4 (#14639)
Closes [#1526](https://github.com/twentyhq/core-team-issues/issues/1526)

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-09-24 18:29:05 +02:00
MarieandGitHub 8d78032357 Implement groupBy resolver (with orderBy, without viewId) (#14690)
Closes
https://github.com/twentyhq/core-team-issues/issues/248?issue=twentyhq%7Ccore-team-issues%7C1543

In this PR
- Implementation of groupBy resolver, without pagination, without viewId
parameter
- introduction of new GqlInputTypeDefinitionKind `OrderByWithGroupBy`
which differs from `OrderBy` as it should use aggregations as order by
conditions (e.g.: OrderByWithGroupBy should use avgEmployees and not
employees which does not make sense)
- Minor refacto of all orderBy expressions to use orderBy signature with
`OrderByCondition` which is usable for both groupBy queries and
non-groupBy queries. groupBy queries differ because their orderBy
conditions are based on aggregatedFields (such as avgEmployees) for
which we can't use the same orderBy signature
<img width="728" height="216" alt="Capture d’écran 2025-09-24 à 15 07
14"
src="https://github.com/user-attachments/assets/aa5c0875-cf38-4d4b-be70-f4d64da77a41"
/>

- Minor refacto to add table name in aggregates expressions
`(AVG("employees") -> AVG("company"."employees")` to keep having the
table names in the orderBy expression as we already had. Since we use
common utils for orderBy and aggregates on findMany this change also
impacts findMany queries with aggregates. It also impacts field
permission check where we extract the name of the selected fields to
check permission on, so I also updated that (see
`extractColumnNamesFromAggregateExpression`)
2025-09-24 16:00:55 +00:00
Baptiste DevessierandGitHub d477db261a Add basic support for iterators in workflow runs (#14680)
## Workflow

<img width="3456" height="2234" alt="CleanShot 2025-09-24 at 11 50
49@2x"
src="https://github.com/user-attachments/assets/c9db9f27-9c0a-4b77-ac49-330e6f934a9e"
/>

## Workflow run

<img width="3456" height="2234" alt="CleanShot 2025-09-24 at 11 50
56@2x"
src="https://github.com/user-attachments/assets/c95d984f-03f0-4aa2-9677-dc86d851172f"
/>
2025-09-24 14:12:15 +00:00
Charles BochetandGitHub 58e1a2261d Debug webhook job (#14675) 2025-09-24 15:47:49 +02:00
Thomas TrompetteandGitHub 3b1657b6fa Store history when iterator reset the step info (#14684)
- before reseting the step, enrich info with previous result
- reset only when a step is executed more than once. This will avoid to
store the initial `NOT_STARTED` status of the step
2025-09-24 13:28:50 +00:00
EtienneandGitHub f5c5ee5645 update cleaning job to progressively delete metadata (#14596)
Workspace cleaning jobs slow down the db each hours when running. We
suspect the object metadata deleting query with all cascade/depending
entities (field, index, ..) to be the cause.
2025-09-24 13:18:56 +00:00
WeikoandGitHub f566f39292 Add FK creation in migration v2 (#14685)
## Context
-
packages/twenty-server/src/engine/metadata-modules/object-metadata/utils/build-default-relation-flat-field-metadatas-for-custom-object.util.ts
Fixing targetFlatFieldMetadata not being accurate for default relation
during object creation (was not used yet)
-
packages/twenty-server/src/engine/twenty-orm/workspace-schema-manager/services/workspace-schema-foreign-key-manager.service.ts
Simplifying API + Removing unused methods and the ones that were
querying pg schema as we want to avoid those as much as possible
-
packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/field/services/create-field-action-handler.service.ts
Adding FK creation when Join column is created
2025-09-24 15:07:50 +02:00
Raphaël BosiandGitHub b0e56e4717 Create MenuPicker (#14681)
Closes https://github.com/twentyhq/core-team-issues/issues/1534

<img width="746" height="324" alt="CleanShot 2025-09-24 at 14 32 52@2x"
src="https://github.com/user-attachments/assets/6c36fe37-b945-4d43-917c-424e7b346902"
/>
2025-09-24 12:43:05 +00:00
21b7cda7af i18n - translations (#14683)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-24 14:22:56 +02:00
Raphaël BosiandGitHub 66a6190e3c Create save dashboard record action (#14665)
Closes https://github.com/twentyhq/core-team-issues/issues/1502

- Created the save action
- Removed the temporary data attribute from the page layout widget since
we will connect widgets to real data soon



https://github.com/user-attachments/assets/2b46b511-f2c2-4e11-873c-a76fd31704e5
2025-09-24 12:03:27 +00:00
a067d961f7 i18n - translations (#14677)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-24 10:49:20 +02:00
neo773GitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix MalfaitFélix Malfait
a1ad8e3a1e Outbound message domains (#14557)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-24 10:33:04 +02:00
Thomas TrompetteandGitHub 6ea7aea92b Migrate update step changes to diff (#14663)
This PR should fix optimistic rendering issues on step updates:
- compute a diff for trigger and steps on mutations
- build an util that applies that diff (built a more robust version from
https://github.com/AsyncBanana/micropatch)
- apply diff in cache
2025-09-23 16:41:26 +00:00
a5c47a60d0 i18n - translations (#14667)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-23 18:17:10 +02:00
09dd49d6d6 feat: Added workspace-level impersonation module and functionality (#14360)
## Description

- This PR is focused on issue
https://github.com/twentyhq/core-team-issues/issues/1421
- Added workspace-level impersonation apart from current
server-level-impersonation
- Introduced WorkspaceImpersonationModule, including service and
resolver for user impersonation within workspaces.
- Enhanced AdminPanelService and AdminPanelResolver to support
impersonation logic, including authentication checks and token
generation.
- added Member Management Interface in settings/members table
- added GraphQL mutation for workspace-level impersonation



## Visual Proof

<img width="919" height="444" alt="Screenshot 2025-09-09 at 1 29 22 AM"
src="https://github.com/user-attachments/assets/a361c6eb-03de-48db-b68a-7d3a489fafde"
/>


https://github.com/user-attachments/assets/454bc1aa-8b8f-4de1-9304-7c147da71dd4


## Impersontion Cookie

<img width="1792" height="297" alt="Screenshot 2025-09-11 at 9 44 06 PM"
src="https://github.com/user-attachments/assets/a8a37d5e-d38d-4472-94a7-4e4b36fba14e"
/>



<img width="1235" height="1041" alt="Screenshot 2025-09-19 at 1 24
09 AM"
src="https://github.com/user-attachments/assets/875e8f9c-e0cb-404b-8291-8fadc6c2a163"
/>

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-09-23 18:07:53 +02:00
nitinandGitHub 8b2726b3fb [Dashboards] - Fix seeding not working for YC workspace because of duplicate IDs (#14591) 2025-09-23 18:01:56 +02:00
martmullandGitHub 5105b4284e Remove twenty-app.jsonc (#14662)
As title, use package.json instead of twenty-app.jsonc
2025-09-23 16:54:24 +02:00
Baptiste DevessierandGitHub bbc97f4ab3 Allow nodes connection to loop edge (#14661)
## Before


https://github.com/user-attachments/assets/4cfb01cb-559a-4cfa-89d6-ee991a5e2550

## After


https://github.com/user-attachments/assets/236e81b0-4f1f-44c5-8714-aa6f1c9358e1

Closes https://github.com/twentyhq/core-team-issues/issues/1521
2025-09-23 13:59:30 +02:00
Raphaël BosiandGitHub 7cb294169d Add a new graphql mutation in the pageLayout resolver to handle page layout update with tabs and widgets (#14612)
Add a new graphql mutation in the pageLayout resolver to handle page
layout update with tabs and widgets.

Later we will add validation inside the service to check if the page
layout tab structure is correct (for instance check widgets don't
overlap or aren't out of the grid, or to check that they have a correct
configuration ...).

This mutation will be plugged to the save action of the dashboards in
the frontend.
2025-09-23 11:00:36 +02:00
Paul RastoinandGitHub fbd3286792 Index v2 side effects (#14567)
# Introduction
Honestly this implem is a mess, discussing a potential side effect
handler with @weiko before the build and run that would handle each side
effect per entity and operation

Handling:
- [ ] unique index is generated when a field is updated with the
`isUnique`
- [x] an index is generated when a relation is created
- [x] search vector index creation on custom object creation
- [x] renaming a field metadata or an object should re-create all
related indexes which are composed by their namings
- [x] delete object should remove any related indexes
- [x] delete field should update related indexes ( if index ends up
empty it should be removed )
- [ ] on object renaming that contains morph fields -> triggers update
field -> trigger index recompute
- [x] on update name renaming should recompute all related indexes

## TODO
- [x] Integration testing
- [ ] Refactor the index maps cache to be storing a
`idsByObjectMetadataId`
- [x] Refactor deterministic name to use order sorting
- [x] Remove flat index from flat object

## What's next

Will handle morph indexes in a new dedicated PR for the moment will
stick to this
Same for the cache improvement and uniqueness
2025-09-23 10:57:11 +02:00
d0b9c7f076 i18n - translations (#14658)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-23 10:48:38 +02:00
Raphaël BosiandGitHub 3d27a1e48a Create a cancel action to leave the dashboard edit mode without saving (#14650)
Closes https://github.com/twentyhq/core-team-issues/issues/1523
2025-09-23 10:36:37 +02:00
1a1ef9f254 i18n - translations (#14656)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-23 09:32:26 +02:00
neo773andGitHub 0011864f9f Fix/preserve channels on credential update (#14633)
https://github.com/user-attachments/assets/6165f177-c32d-4ddf-8991-3986f01897ee


/closes #14522
2025-09-23 09:22:39 +02:00
6f49481095 Imap perf improvement (#14629)
- Removed buffer to string conversion on message and we instead pass the
direct Buffer
- Removed redundant flattening of results
- Cached `JSDOM` and `DOMPurify` Instance
- MailParser added `skipTextToHtml` along with some other options, which
reduced parsing time from 50ms to 35ms

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-23 09:21:30 +02:00
216d72b5d7 AI SDK v5 migration (#14549)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-22 22:13:43 +02:00
martmullandGitHub e8121919bd Remove twenty-apps irrelevant stuff (#14649)
As title

twenty-apps is the public repository for public twenty applications. One
small hello-world application is registered here, will be useful for
development
2025-09-22 21:06:17 +02:00
martmullandGitHub 68882ec483 Merge commands (#14647)
- duplicates between install and deploy commands
- remove list command that call findManyAgents
2025-09-22 16:26:01 +02:00
WeikoandGitHub 40240ce514 Add view viewField favorite creation after object creation in migration v2 (#14644)
## Context
We are not exactly sure how we want to handle side effects with
workspace migration v2, in the meantime I'm re-introducing this part in
the caller (object v2 service)
2025-09-22 16:19:38 +02:00
martmullandGitHub f76e9df3cd Remove verbose option (#14646)
as title
2025-09-22 15:19:57 +02:00
Lucas BordeauandGitHub d6e4bcb533 Fix table column width on mobile (#14623)
This PR fixes some minor issues to have all width computation working
properly and table displaying nicely on mobile.
2025-09-22 10:18:12 +02:00
d308f5adf9 i18n - translations (#14634)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-21 17:20:09 +02:00
9a2766feae feat: rich text email body (#14482)
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-21 16:55:34 +02:00
Antoine MoreauxandGitHub a89e5d0f27 feat(database): activate unaccent extension with immutable function (#14621) 2025-09-21 15:17:19 +02:00
Abdullah.andGitHub 646aecece1 Update integration test to include cases for bi-directional accent-insensitive search. (#14631)
## Summary

Enhanced the search resolver integration tests to comprehensively
validate bidirectional accent-insensitive search functionality. Users
can now search with or without accents and find all relevant records
regardless of how the data was originally stored.

## Changes Made

### Test Data Enhancements

- Added 2 new person IDs: `TEST_PERSON_6_ID`, `TEST_PERSON_7_ID`
- Expanded corpus from 5 to 13 records:
  - 7 persons
  - 2 companies
  - 4 pets
- Refactored test data into single arrays with content-driven variable
naming for better maintainability

### Test Coverage Improvements

- Added 6 comprehensive bidirectional tests covering French, Spanish,
and German characters
- Validated multiple fields:
- `firstName`, `lastName`, `jobTitle`, `email`, `company name`, `pet
name`
- Cross-object search testing across Person, Company, and Pet
- Updated all ranking values to account for the enlarged test corpus (5
→ 13 records)

## Test Cases Added/Updated

- [x] should find both **"José"** and **"Jose"** when searching for
`"jose"` (bidirectional accent-insensitive)
- [x] should find both **"García"** and **"Garcia"** when searching for
`"garcia"` (bidirectional accent-insensitive)
- [x] should find both accented and non-accented **"Café"** / **"Cafe"**
records when searching for `"cafe"` (bidirectional accent-insensitive)
- [x] should find both accented and non-accented **"Naïve"** /
**"Naive"** records when searching for `"naive"` (bidirectional
accent-insensitive)
- [x] should find both **"Müller"** and **"Muller"** when searching for
`"muller"` (bidirectional accent-insensitive)
- [x] should find both **"François"** and **"Francois"** when searching
for `"francois"` (bidirectional accent-insensitive)
2025-09-21 08:47:14 +02:00
Thomas des FrancsandGitHub f851879e0f 1.6 changelog (#14620)
workflows improvements!
2025-09-20 12:41:37 +02:00
Charles BochetandGitHub a21daa2670 Optimize CI runner cost (#14628) 2025-09-20 12:14:29 +02:00
Abdullah.andGitHub ff3467c18e feat (search): add dynamic search field metadata foundation for database-driven search configuration (#14469)
## Summary

Implements the foundation for dynamic search field configuration from
[issue #1428](https://github.com/twentyhq/core-team-issues/issues/1428).

## Changes

- Add `SearchFieldMetadataEntity` junction table for storing searchable
field configurations
- Add `SearchFieldMetadataService` with core CRUD operations  
- Add `SearchFieldMetadataModule` following existing patterns  
- Add `IS_DYNAMIC_SEARCH_FIELDS_ENABLED` feature flag (defaults to
`false`)
- Database migration with proper indexes and foreign keys  

## Architecture

Uses a junction table where **record existence = field is searchable**:

**Table: `searchFieldMetadata(objectMetadataId, fieldMetadataId,
workspaceId)`**

- Unique constraint on `(objectMetadataId, fieldMetadataId)`  
- `ON DELETE CASCADE` on foreign keys  

## Testing

- [x] Migration runs successfully  
- [x] Table created with correct schema  
- [x] Feature flag seeded properly  
- [x] Database reset works correctly  

## Next Steps

Future PRs will handle:

- Data migration from existing hardcoded search field configs  
- Integration with search services  

 No breaking changes — fully backward compatible.
2025-09-19 18:35:51 +02:00
Charles BochetandGitHub a89cc3b234 Fix messaging crons (#14619)
## Context

While refactoring messaging, I forgot that workspaces that have been
created before july do not have 'CALENDAR_EVENT_LIST_FETCH_PENDING' and
'MESSAGE_LIST_FETCH_PENDING' enum values (as we don't sync-metadata the
enum values, we would need a migrate command that has not been written
yet)

In the current implementation CALENDAR_EVENT_LIST_FETCH_PENDING =
FULL_CALENDAR_EVENT_LIST_FETCH_PENDING, so I'm putting it back as it was
before
2025-09-19 17:26:05 +02:00
Lucas BordeauandGitHub aff3a300fe Refactored table width and height constants (#14613)
This PR essentially refactors some hard-coded values for width and
height in the table.

It also fixes a few differences from the Figma design, on the checkbox
column width and the top bar and view bar left alignment with the table.

The blue color has been set like before the refactor of the focus portal
(`theme.adaptiveColors.blue4`)

Fixes in https://github.com/twentyhq/core-team-issues/issues/1490 : 
- Fix first drag and drop column width that has changed from main (see
Figma)
- Unify all widths, heights, z-index, etc. with constants
- Put same blue as before for focused portal

Also removed `focus-active` class because we now use a portal for the
focus.
2025-09-19 17:19:26 +02:00
8ba1dc1d94 Added a util helper to remove accent and case to improve search logic (#14533)
# [WIP] Make Local Search Non-Accent-Sensitive

fixes(#14468)

---

**Description:**  
This PR adds accent- and case-insensitive search for the
**SettingsWorkspaceMembers** component’s local search. It ensures that
searching for names or emails works correctly even if the user types
letters without accents.

**Implementation:**  
- Added a helper util: `removeAccentsAndCase(text: string)`  
- This util:
  - Normalizes text to NFD form
  - Removes diacritics (accents)
  - Converts text to lowercase
- Replaced current `.includes(searchFilter)` logic with a normalized
comparison:


---

### Video ->

[Screencast from 2025-09-16
16-42-50.webm](https://github.com/user-attachments/assets/7035906c-9c5d-414d-81e5-74e53803628a)


---

Opening a draft pr for initial strategy review before extending it to
other components.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-09-19 17:03:43 +02:00
Antoine MoreauxandGitHub deed08ba25 fix(billing): reenable trial (#14616)
…reation
2025-09-19 15:16:57 +02:00
Baptiste DevessierandGitHub 5311b07ae8 Support loops in workflow versions (#14603)
## In the workflow

<img width="3456" height="2160" alt="CleanShot 2025-09-18 at 17 57
23@2x"
src="https://github.com/user-attachments/assets/5041f1d8-ea43-44f5-b3f3-012054b0352d"
/>

## In the workflow version

<img width="3456" height="2234" alt="CleanShot 2025-09-18 at 17 57
32@2x"
src="https://github.com/user-attachments/assets/37137907-f00d-448c-ab81-0d5ee55b0437"
/>

Closes https://github.com/twentyhq/core-team-issues/issues/1452
2025-09-19 15:07:22 +02:00
Paul RastoinandGitHub 39661db3c8 Setup 1.6 commands (#14614) 2025-09-19 12:32:13 +00:00
Charles BochetandGitHub 349b15e81f Add scripts to relaunch message and calendar channels (#14579)
## Context

1. We are debugging the experience on messaging and calendar sync. I'm
adding two scripts to relaunch messaging and calendar channels
2. We are seeing errors in Sentry regarding microsoft drivers errors. I
was about to fix them but I'm refactoring / simplifying a bit the logic
first. It will be a betters starting point
2025-09-19 12:31:19 +02:00
MarieandGitHub 4a6ad48a62 Fix - Record text should always be visible and in first position in views (#14598)
Fixes https://github.com/twentyhq/twenty/issues/14442

Issues were
1. Table headers always used label metadata identifier (or record text)
as first column, while table body followed viewFields positions
2. Label metadata identifier should always be visible and in first
position for the table views to work as expected, while when updating
the label metadata identifier for an object, no changes were brought to
the viewFields

To fix that
1. In the BE: 
- a new logic is implemented to i) update label identifier's viewFields
position and visibility when an object's label identifier is updated to
a new field; ii) add validation on the update of a viewField's position
and visibility to make sure the label identifier's viewField always has
the lowest position + is visible
- a command was added to check all existing views and viewfields
3. In the FE: at first I tried to replicate the logic of the headers
(based on the label identifier rather than the positions) on the body,
but it was too complex and error-prone as in multiple places we are
based on the positions. It also feels more right to have only one source
of truth which is the viewField position. @lucasbordeau if that does not
suit you, we can throw an error if the field with the lowest position is
not the label metadata identifier, as you said the table view will be
very buggy / wont work if the label identifier is not in the first
position. but now it should never be the case thanks to the validation
implemented in the BE

This should be migrated to viewFieldService V2 when relevant @Weiko
@prastoin
2025-09-19 10:24:09 +00:00
43e0cd5d05 feat(billing): refacto billing (#14243)
… prices for metered billing

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-19 11:25:53 +02:00
Lucas BordeauandGitHub 163890f6c8 Add back shadow on frozen columns and header in table (#14593)
This PR adds back box-shadow on header and first frozen columns of the
table, they appear at scroll.

With the recent refactor and the removal of a lot of re-render, and the
usage of CSS variables, it is now completely fluid.

# Before 

<img width="500" height="234" alt="image"
src="https://github.com/user-attachments/assets/9735acb0-5951-4a2d-845c-49e917e99053"
/>

<img width="576" height="242" alt="image"
src="https://github.com/user-attachments/assets/328654bf-97c7-43a2-86b1-0f100ed60daa"
/>

# After 

<img width="455" height="250" alt="image"
src="https://github.com/user-attachments/assets/3450a63f-4d6f-45ed-bfd2-3c10856b21a7"
/>

<img width="488" height="244" alt="image"
src="https://github.com/user-attachments/assets/1057a391-3a98-4b5e-97f1-890f79e6f8d0"
/>
2025-09-19 10:40:32 +02:00
Thomas TrompetteandGitHub 6d5635f4e2 Use variables within Iterators (#14604)
Variables were not working properly. Output schema was outdated and
parent steps were not calculated properly.

Before


https://github.com/user-attachments/assets/b070c1ff-41dd-4ea0-a590-25bb39027456

After


https://github.com/user-attachments/assets/baa43e69-0e7c-4697-8812-3ce523efba13
2025-09-18 23:13:57 +02:00
Charles BochetandGitHub c7005db860 Fix sort bug issue (#14607)
Enum should not receive any special treatment when building order by
2025-09-18 20:23:19 +02:00
Baptiste DevessierandGitHub 4d994fc566 Improve edge path algorithm (#14600)
https://github.com/user-attachments/assets/795b8293-60d2-44de-b261-7db093716e14

Closes https://github.com/twentyhq/core-team-issues/issues/1470
2025-09-18 17:43:42 +02:00
Thomas TrompetteandGitHub 80fec01707 [Iterator] Add position offset to empty node (#14597)
As title. Took the offset from figma



https://github.com/user-attachments/assets/e81083fe-ef81-49a0-b150-e67fda428cd3
2025-09-18 16:22:38 +02:00
6496b9a5e4 i18n - translations (#14595)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-18 15:14:11 +02:00
Thomas TrompetteandGitHub 3fbc257c06 Make filters a regular step (#14586)
- Remove special design logic for filters and edge with filters
- Remove backend logic to delete filters along with parent steps
- Add filters to the node type picker



https://github.com/user-attachments/assets/5b6ceda4-d86f-48a3-8c93-37a885398a8d
2025-09-18 13:07:23 +00:00
Paul RastoinandGitHub 235eef32f6 Improve builder return type (#14592)
We need grain in orchestrator over actions ordering for upcoming index
integration to v2
2025-09-18 12:42:01 +00:00
714b466fd5 i18n - translations (#14590)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-18 11:46:01 +02:00
Lucas BordeauandGitHub b4e386192d Table small fixes (#14588)
This PR brings more UX fixes for table.

Fixes in https://github.com/twentyhq/core-team-issues/issues/1490 : 
- Fix any field filter chip formatting
- Empty placeholder should be centered on screenwidth and not scrollable
width on table
- First cell is automatically active on table but we can't move => We
now allow focus position to be null as it is a portal

Fixes https://github.com/twentyhq/twenty/issues/14573
2025-09-18 11:29:33 +02:00
Saurav JainandGitHub db8d8e8400 fix: Added isReadonly logic to css (#14584)
### Description

Field values in RecordInlineCell were disappearing on hover even when
read-only.
This was caused by the hover CSS being applied unconditionally and
readonly prop not used properly.

Fixes #14582  
---

### Changes

- Added $readonly prop to StyledValueContainer to conditionally apply
hover opacity.

- Read-only fields now display values normally;

---

### Video ->

[Screencast from 2025-09-18
06-17-20.webm](https://github.com/user-attachments/assets/d1ad8a0a-5903-4709-b02a-77ae2e1315f1)
2025-09-18 10:55:00 +02:00
Lucas BordeauandGitHub ea02b4ffac Fixes hover + focus on same cell (#14580)
Fixes in https://github.com/twentyhq/core-team-issues/issues/1490: 
- Hover portal missing on task row
2025-09-18 10:24:34 +02:00
c582eaea4d i18n - translations (#14583)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-17 23:20:01 +02:00
dc26e48f6f fixing Numbers formatting (#14403)
fix #13880

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-09-17 23:03:33 +02:00
666b99524a remove singleton usage of i18n (#14422)
closes https://github.com/twentyhq/core-team-issues/issues/1480

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-09-17 19:01:43 +02:00
Lucas BordeauandGitHub 2ffbe017c2 Fix focused row group section border bottom (#14577)
This PR fixes the focused row that was making the group section border
bottom disappear if collapsed.

In https://github.com/twentyhq/core-team-issues/issues/1490, fixes : 
- Section border-bottom disappear if the focus is on the first row of a
collapsed section
2025-09-17 18:56:49 +02:00
Charles BochetandGitHub f3adce0773 Fix one to many relation and multi select fields on table (#14576)
Fixes:
- relation one to many cannot be set (we have deprecated limit: keyword
in graphql at it was not use, we should only use first or last)
- https://github.com/twentyhq/twenty/issues/14556
2025-09-17 18:55:02 +02:00
3a5ba1673b i18n - translations (#14578)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-17 18:21:37 +02:00
Raphaël BosiandGitHub 0750bcaefc Create edit dashboard action (#14564)
Closes https://github.com/twentyhq/core-team-issues/issues/1435

Introduced a new pattern to force to register an action or not.
Discussed this with @charlesBochet
2025-09-17 15:58:26 +00:00
1c8dccda01 i18n - translations (#14575)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-17 17:45:43 +02:00
Thomas TrompetteandGitHub 8b345c9fd2 Change workflow node type (#14570)
- Update step endpoint now supports the case where node type is updated
- Added a new page for edition that re-uses the existing select action
component

Additional work:
- moved submitForm function to workflow runner service



https://github.com/user-attachments/assets/1fcb0adc-fe17-41f9-b2ea-4f84318db860
2025-09-17 15:36:42 +00:00
Lucas BordeauandGitHub 0098ac453c Fixes z-index with groups (#14563)
This PR fixes a few z-index issues on table with groups.

Once the z-index issues will have been stabilized, we'll refactor this
big constant file which is hard to maintain.

In https://github.com/twentyhq/core-team-issues/issues/1490, fixes : 
- Aggregate footer label identifier is hidden
- Bug sticky footer label identifier on table with groups has not the
right z-index
2025-09-17 17:17:36 +02:00
Félix MalfaitGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
fda3183ba6 Add missing migration for unaccent (#14566)
It was in setup-db.ts but that's not enough for instances that are
already live

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-09-17 17:13:49 +02:00
04b1019ca4 i18n - translations (#14571)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-17 17:01:06 +02:00
MarieandGitHub 53b853f877 [fix] Handle null icon for field metadata (#14565)
Fixes https://github.com/twentyhq/twenty/issues/14548.

When creating a field metadata through the api, the field's icon can be
null (from twenty UI, a default icon is always added by default and it
is not possible to remove it). Then this value is turned into an empty
string in the payload - i don't know why we don't send the null value.
When updating the field through the UI, we run a zod validation that
either accepts a null value for Icon, or a value that starts with
`"Icon".` In our case, the value for Icon was `""` (an empty string),
which is not valid. Therefore the form was considered not valid until an
icon was added.

While the fix suggested works, we should probably sort out the `null`
conversion to `""`, as it is prone to errors.
2025-09-17 16:58:17 +02:00
nitinandGitHub bc471deaba [Dashboards] - refactor - gauge and number chart (#14550)
This is the fourth and last PR from the split of
https://github.com/twentyhq/twenty/pull/14458 - refactoring PieChart and
NumberChart widgets.
2025-09-17 14:44:50 +00:00
nitinandGitHub 09b9071182 [Dashboards] - Add scroll wrapper (#14561)
## Summary
  - Fixed nested scrolls and sticky tabs in dashboard view
  - Drag select now auto-scrolls via ScrollWrapper context

## Changes
- Wrapped content in ScrollWrapper which provides context ID
automatically
  - Removed overflow from grid container to fix nested scrolls
2025-09-17 15:39:22 +02:00
d841b0d0db i18n - translations (#14560)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-17 15:14:16 +02:00
Paul RastoinandGitHub 2d8669ae71 Index v2 runner (#14537)
## Introduction
https://github.com/twentyhq/twenty/pull/14363
In this PR we're creating builder and runner for index metadata
Removing its previous integration within object builder

## Next:
- implem index impact on field and object metadata api
- Add integration testing coverage add integration test on index
- Implement uniqueness toggle in field metadata api
- add integration test on uniqueness

related to https://github.com/twentyhq/core-team-issues/issues/1344
2025-09-17 13:02:43 +00:00
Lucas BordeauandGitHub 6e47c1b5c6 Fix column resize handle (#14559)
This PR fixes the column resize handle issues.

Fixes in https://github.com/twentyhq/core-team-issues/issues/1490 : 
- We see the pointer blink when resizing => Already here before
refactor, this is because the mouse enter / leave events shouldn't be
triggered while resizing.
- Resizing handle sometimes cannot be clicked anymore / does not appear
anymore (see if another listener doesn't prevent this)

The code will need to be cleaned after all fixes have been done though
has it duplicates logic between the different header components.
2025-09-17 14:39:44 +02:00
EtienneandGitHub 24204b2928 Group By - Add feature flag (#14558)
Tested : 
- workspace needs to flush cache after activating feature flag 
- workspace does not need to flush cache if ff false and coming from
previous version (before gql schema gen updates)
2025-09-17 11:42:11 +00:00
WeikoandGitHub ddb4cf0c8c various UI fixes in calendar view (#14551) 2025-09-17 12:45:40 +02:00
814c30e775 i18n - translations (#14555)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-17 11:40:55 +02:00
8d9617131c Feat: Add reasoning summary and tool details display for AI responses (#14414)
Closes [#1405](https://github.com/twentyhq/core-team-issues/issues/1405)

### Implemented Features
- Reasoning Summary: Collapsible display of AI thinking process with
real-time streaming
- Tool Execution: Detailed tool call rendering with expandable results
and loading states
- Error Handling: Clean error stream event display with proper
formatting


### Demo



https://github.com/user-attachments/assets/76ad29b7-d831-4bc8-a115-ad25f7ace6e2

<img width="504" height="819" alt="Screenshot 2025-09-12 at 3 23 39 AM"
src="https://github.com/user-attachments/assets/82dc177d-f009-4e8a-8901-ee1a49201984"
/>

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-17 11:30:24 +02:00
1bf6821b07 i18n - translations (#14553)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-17 11:21:21 +02:00
martmullandGitHub f6530abdf4 Add settings section for public domains (#14543)
As title



https://github.com/user-attachments/assets/1c2adb14-0fc1-4623-88bc-10ff729c72a1
2025-09-17 09:07:02 +00:00
Lucas BordeauandGitHub 7309717ed7 Fix table footer cell resize issue (#14552)
This PR fixes issues about the resizing of footer cell.

Fixes in https://github.com/twentyhq/core-team-issues/issues/1490 :
- Resizing doesn't move footer cell
- Fix column min width (create a constant file with 104px)
2025-09-17 08:43:11 +00:00
EtienneandGitHub dc435a7946 Add default limit when fetching records (#14532)
- set default limit on front find many hooks
- use default constant in rest api find many endpoint
- set a max limit in rest api find many endpoint
2025-09-17 10:32:47 +02:00
EtienneandGitHub 61b9d82950 create groupBy resolver + mock groupBy service (#14530)
To test :

```
query : 
query companiesGroupBy($groupBy: CompanyGroupByInput){
  companiesGroupBy(groupBy: $groupBy){
    groupByDimensionValues
    countEmptyId
    sumAnnualRecurringRevenueAmountMicros
    countEmptyAddress
    percentageEmptySearchVector
  }
}

input : 
{"groupBy": {"name": true, "employees": true, "domainName": {"primaryLinkUrl": true}}}

response : 
{
  "data": {
    "companiesGroupBy": [
      {
        "groupByDimensionValues": [
          "Text 1",
          "twenty.com",
          "1"
        ],
        "countEmptyId": 39,
        "sumAnnualRecurringRevenueAmountMicros": 20,
        "countEmptyAddress": 56,
        "percentageEmptySearchVector": 88
      },
      {
        "groupByDimensionValues": [
          "Long long long long and long text 2",
          "github.com/twentyhq/twenty",
          "2"
        ],
        "countEmptyId": 20,
        "sumAnnualRecurringRevenueAmountMicros": 56,
        "countEmptyAddress": 88,
        "percentageEmptySearchVector": 2
      },
      {
        "groupByDimensionValues": [
          "Text 3",
          "react.dev",
          "3"
        ],
        "countEmptyId": 56,
        "sumAnnualRecurringRevenueAmountMicros": 88,
        "countEmptyAddress": 2,
        "percentageEmptySearchVector": 39
      }
    ]
  }
}
```
closes https://github.com/twentyhq/core-team-issues/issues/1439
2025-09-17 10:23:34 +02:00
Lucas BordeauandGitHub 2430f21d83 Fixed last column width bug on table with groups (#14541)
This PR fixes the last column of a table with groups that was wrapping
on a new line on a empty table or its filtering equivalent (filter
without result)

Fixes in https://github.com/twentyhq/core-team-issues/issues/1490 :
- Fixes most urgent : Empty table with groups header wraps
- Fixes less urgent : Resizing a table with groups makes some filling
resize in the wrong direction
2025-09-17 10:04:02 +02:00
2a7a83de81 feat(search): Add unaccent support for accent-insensitive search. (#14464)
##  Add accent-insensitive search functionality

### 🎯 Overview
Implements accent-insensitive search across all searchable fields in
Twenty CRM.
Users can now search for "jose" to find "José", "muller" to find
"Müller", "cafe" to find "café", etc.

### 🔍 Problem
Twenty's search functionality was accent-sensitive, requiring users to
type exact accented characters to find records.
This created a poor user experience, especially for international names
and content.

### 💡 Solution
Added PostgreSQL `unaccent` extension with a custom immutable wrapper
function to enable accent-insensitive full-text search across all
searchable field types.

### 📋 Changes Made
**Modified Files:**  
- `packages/twenty-server/scripts/setup-db.ts`  
-
`packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-where-condition-parts.ts`
-
`packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util.ts`

### 🗄️ Database Setup (`setup-db.ts`)
```sql
-- Added unaccent extension
CREATE EXTENSION IF NOT EXISTS "unaccent";

-- Created immutable wrapper function
CREATE OR REPLACE FUNCTION unaccent_immutable(text) RETURNS text AS $$
  SELECT public.unaccent($1)
$$ LANGUAGE sql IMMUTABLE;
```

### 🔍 Search Vector Generation
(`get-ts-vector-column-expression.util.ts`)
Applied `public.unaccent_immutable()` to all searchable field types:  
- TEXT fields (job titles, names, etc.)  
- FULL_NAME fields (first/last names)  
- EMAILS fields (both email address and domain)  
- ADDRESS fields  
- LINKS fields  
- RICH_TEXT and RICH_TEXT_V2 fields

### 🔎 Query Processing (`compute-where-condition-parts.ts`)
Enhanced search queries to use `public.unaccent_immutable()` for both:  
- Full-text search (`@@` operator with `to_tsquery`)  
- Pattern matching (`ILIKE` operator)

### 🧠 Technical Rationale: Why the Wrapper Function?
**The Challenge:**  
PostgreSQL's built-in `unaccent()` is marked as **STABLE**, but
`GENERATED ALWAYS AS` expressions (used for search vector columns)
require **IMMUTABLE** functions.

**The Solution:**  
Created an IMMUTABLE wrapper function that calls the underlying
`unaccent()` function:
-  Satisfies PostgreSQL's immutability requirements for generated
columns
-  Maintains the exact same functionality as the original `unaccent()`
-  Uses fully qualified `public.unaccent_immutable()` to ensure
function resolution from workspace schemas

**Alternative Approaches Considered:**  
-  Modifying `search_path`: would affect workspace isolation  
-  Computing unaccent at query time: would hurt performance  
-  Using triggers: would complicate data consistency

### 🎯 Impact
For **Person** records, accent-insensitive search now works on:  
- Name (first/last name): `"jose garcia"` finds `"José García"`  
- Email: `"jose@cafe.com"` finds `"josé@café.com"`  
- Job Title: `"manager"` finds `"Managér"` or `"Gerente de Café"`

Applies to all searchable standard objects:  
- Companies, People, Opportunities, Notes, Tasks, etc.  
- Any custom fields of searchable types (TEXT, EMAILS, etc.)

###  Testing
- Database reset completes successfully  
- Workspace seeding works without errors  
- Search vectors generate with unaccent functionality  
- All searchable field types properly handle accented characters

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-09-17 09:01:35 +02:00
Thomas des FrancsandGitHub f8a842781d feat: add changelog & image for 1.5 (#14412) 2025-09-16 18:10:47 +02:00
Thomas TrompetteandGitHub 5695202d31 Fix variables coming from DB events (#14545)
In the case of DB events, id field will be prefixed with
'property.after'. This is why we need to use the fieldIdName when
provided.

Before: When providing only id, Company variable is {{trigger.id}}.
Which does not exists on DB event output schema
<img width="939" height="462" alt="Capture d’écran 2025-09-16 à 17 57
42"
src="https://github.com/user-attachments/assets/c46dc00a-bb0e-45b9-af42-e9ddd0a08aea"
/>

After: Company variable is {{trigger.property.after.id}}
<img width="939" height="578" alt="Capture d’écran 2025-09-16 à 17 57
14"
src="https://github.com/user-attachments/assets/ede11de0-b98e-40df-89a1-9b283a2692ff"
/>
2025-09-16 16:07:36 +00:00
acccbb1cc4 i18n - translations (#14544)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-16 18:01:09 +02:00
Abdul RahmanandGitHub 172cc12a82 feat: Add xAI models support (#14523) 2025-09-16 17:55:11 +02:00
nitinandGitHub ba3cbd1676 [Dashboards] - refactor - pie chart (#14526)
This is the third PR from the split of
https://github.com/twentyhq/twenty/pull/14458 - refactoring only the
PieChart widget.

Plus small performance improvements on already refactored widgets
2025-09-16 17:44:31 +02:00
Raphaël BosiandGitHub 3b868c3d2a Page layout refactoring (#14535)
In this PR:
- Refactored the page layout renderer
- Converted all the states to component states
- Removed the page layout edition in settings

TODOs in next PRs:
- Fix bug with the drag selector not taking the scroll into account to
display the dragged area
- Readd the tab edition in edit mode
2025-09-16 15:42:51 +00:00
Thomas TrompetteandGitHub e69131790c Put back previous empty option (#14542)
Adding that option puts No Value everywhere. Removing it.
2025-09-16 15:08:44 +00:00
d95ca35faa i18n - translations (#14540)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-16 17:01:08 +02:00
WeikoandGitHub 106da85899 Add dnd to calendar view (#14539) 2025-09-16 17:00:01 +02:00
Thomas TrompetteandGitHub 4b889db06c Add icon to duplicate + split step service in two (#14521)
As title. Created a new step operations service.

Also added Duplicate Icon
<img width="500" height="767" alt="Capture d’écran 2025-09-16 à 09 42
19"
src="https://github.com/user-attachments/assets/4d789639-62f6-4fea-afb8-396868d7c2cb"
/>
2025-09-16 14:45:16 +00:00
Thomas TrompetteandGitHub e9f277fe93 Add form select field (#14538)
- create a WorkflowFormFieldInput component that takes a fieldMetadataId
as input and display a form field input
- add a select field for forms


https://github.com/user-attachments/assets/42f8ce98-c17a-4809-b1be-032e3066a596
2025-09-16 14:26:36 +00:00
4f63f55686 i18n - translations (#14536)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-16 14:59:42 +02:00
Paul RastoinandGitHub 371c26bc9b Flat entity maps cache generic service + runner dynamically retrieving invalidating update cache + view service v2 refactor (#14508)
# Introduction
Migrate previous runner only iterating on `flatObjectMetadataMaps` to
`allFlatEntityMaps`.
Refactored the optimistic to be handled inside the actions handler

## Workspace flat map cache
Introducing a new service and registry, that will dynamically retrieve
and or recompute requested cache when called

## Runner refactor
Runner now dynamically invalidate updated cache at the end of the
transaction

close
https://github.com/orgs/twentyhq/projects/1/views/8?pane=issue&itemId=129136356&issue=twentyhq%7Ccore-team-issues%7C1492
close
https://github.com/orgs/twentyhq/projects/1/views/8?pane=issue&itemId=129136210&issue=twentyhq%7Ccore-team-issues%7C1494
2025-09-16 14:39:42 +02:00
Lucas BordeauandGitHub 8f42c33bd4 Fix table mobile display issues (#14528)
This PR fixes table issues while displaying on mobile, the label
identifier cell and footer cells where using a width not corresponding
to the header cell.

We fix this by creating a shared constant and adapting the CSS for this
case with a media query.

Fixes https://github.com/twentyhq/core-team-issues/issues/1454
2025-09-16 14:20:18 +02:00
69c4b00796 i18n - translations (#14534)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-16 14:01:31 +02:00
Baptiste DevessierandGitHub 60de57f469 Implement creating node before initial step + deleting loop edge (#14525)
https://github.com/user-attachments/assets/d4ef0fa1-89e0-4848-9a4d-93dee81254f7

## Remaining to handle in future PRs

- It would be easier for the frontend if the loop edge was stored in the
backend instead of being an edge case the frontend must handle
- Optimistic rendering when deleting loop edge
2025-09-16 13:50:56 +02:00
WeikoandGitHub e505e9cf9f Add compact view to calendar (#14527)
<img width="1263" height="785" alt="Screenshot 2025-09-16 at 11 44 44"
src="https://github.com/user-attachments/assets/dc61e69f-b887-4a4d-9f9c-e50ffa076082"
/>
<img width="1263" height="785" alt="Screenshot 2025-09-16 at 11 43 45"
src="https://github.com/user-attachments/assets/2dd917b3-6e6d-40f2-bb10-6c82de83c15d"
/>
2025-09-16 12:47:55 +02:00
Baptiste DevessierandGitHub b8ae7ddad9 Disable hover and active styles when button is disabled in primary/default variant (#14524)
Follow up of https://github.com/twentyhq/twenty/pull/14439.

After diving in, it seems primary/default is the only variant that
wasn't protected against this edge case.

## Before


https://github.com/user-attachments/assets/e7b1e61e-8db3-4e0e-82b4-e54c390e744b

## After


https://github.com/user-attachments/assets/bb3b2466-e63d-4727-b520-04f4578d579a
2025-09-16 11:36:32 +02:00
Saurav JainandGitHub 45362c0b12 Added disabled trash button in http in workflows (#14439)
## Summary
Added a disabled Trash button in HTTP workflows to prevent accidental
deletion of certain items.

## Fixes
fixes #14420

## Screenshot

<img width="498" height="852" alt="Screenshot from 2025-09-12 05-37-37"
src="https://github.com/user-attachments/assets/dda8eded-a42b-4a86-bd6b-3d415e39fe3c"
/>

---


Open to review.
2025-09-16 10:57:21 +02:00
Lucas BordeauandGitHub b781da9dfb Fixes table z-index, focus, active rows and cells, pixel perfect (#14519)
This PR fixes z-indices on all cases for table with and without groups.

It also fixes 1px glitches that appeared previously already and also
during this refactor, with active and focused rows.

The focus on cells is no a portal similar to hovered portal, which works
really easily thanks to the z-index management already done on hovered
portal.

The urgent issues here
https://github.com/twentyhq/core-team-issues/issues/1490 have been
fixed.
2025-09-15 22:40:29 +00:00
WeikoandGitHub 91b7ecc0a3 Add current day style in calendar view (#14518)
<img width="1242" height="743" alt="Screenshot 2025-09-15 at 18 36 07"
src="https://github.com/user-attachments/assets/a614534a-e002-4858-ad93-fcb21410795a"
/>
2025-09-15 18:40:06 +02:00
Charles BochetandGitHub 0c4496409a Calendar View: persist field updates (#14517)
<img width="1919" height="956" alt="image"
src="https://github.com/user-attachments/assets/726738db-68fc-4cdc-949a-d2adc29a436c"
/>
2025-09-15 18:38:03 +02:00
WeikoandGitHub fbc4328448 Add grid to calendar view (#14516)
<img width="1254" height="786" alt="Screenshot 2025-09-15 at 18 15 40"
src="https://github.com/user-attachments/assets/3e95b8b9-f877-4527-9793-2f738939ce19"
/>

Next step: fix padding issue with cards
2025-09-15 18:17:21 +02:00
Thomas TrompetteandGitHub 3f112a23a0 Fix loop step ids on insert (#14515)
Existing loop step ids should now be part of the inserted step next step
ids, but not be part of the initialLoopStepIds
2025-09-15 16:15:09 +00:00
Charles BochetandGitHub 755ffe0561 Calendar view: add field edition (#14514)
<img width="1919" height="956" alt="image"
src="https://github.com/user-attachments/assets/4829f6f9-7e53-45da-bc38-590ee2fbde98"
/>
2025-09-15 18:03:06 +02:00
Thomas TrompetteandGitHub 2f1efa68ad Fix manual trigger variables + workflow not found in sentry (#14509)
- Error in
[sentry](https://twenty-v7.sentry.io/issues/6677390012/?environment=prod&environment=prod-eu&project=4507072499810304&query=is%3Aunresolved%20%21issue.type%3A%5Bperformance_consecutive_db_queries%2Cperformance_consecutive_http%2Cperformance_file_io_main_thread%2Cperformance_db_main_thread%2Cperformance_n_plus_one_db_queries%2Cperformance_n_plus_one_api_calls%2Cperformance_p95_endpoint_regression%2Cperformance_slow_db_query%2Cperformance_render_blocking_asset_span%2Cperformance_uncompressed_assets%2Cperformance_http_overhead%2Cperformance_large_http_payload%5D%20timesSeen%3A%3E10&referrer=issue-stream)
: due to workflow being deleted, so not found

- Error with Manual Trigger variable fixed
Before
<img width="1020" height="359" alt="Capture d’écran 2025-09-15 à 16 24
34"
src="https://github.com/user-attachments/assets/0d4b5185-18b5-415f-afbc-8bb63e403c01"
/>

After
<img width="1020" height="359" alt="Capture d’écran 2025-09-15 à 16 24
02"
src="https://github.com/user-attachments/assets/c5b589f8-7abd-40d0-8473-69eab7e1a277"
/>
2025-09-15 15:31:12 +00:00
Charles BochetandGitHub 069956ce92 Add fields on calendar cards (#14513)
<img width="1919" height="956" alt="image"
src="https://github.com/user-attachments/assets/32f3c5b3-3f1e-4279-98ef-5e185f6a7ac1"
/>
2025-09-15 17:28:14 +02:00
Lucas BordeauandGitHub 13c1e63892 Fix hovered portal on table with groups (#14512)
This PR fixes https://github.com/twentyhq/twenty/issues/13022 

It was due to a mouse leave event that worked for table without groups
but not with table with groups, the fix is to handle this event higher
up in the table.

This PR also fixes a bug that happened when hiding a column, the page
crashed because of an indexed array returning undefined that TS didn't
catch, linked to
https://github.com/twentyhq/core-team-issues/issues/1205.
2025-09-15 17:28:01 +02:00
nitinandGitHub 24b7075f60 [Dashboards] - refactor - line chart (#14507)
This is the second PR from the split of
https://github.com/twentyhq/twenty/pull/14458 - refactoring only the
LineChart widget.
2025-09-15 20:29:22 +05:30
WeikoandGitHub e8c7dd8380 add date picker on calendar view (#14511)
<img width="1280" height="352" alt="Screenshot 2025-09-15 at 16 34 50"
src="https://github.com/user-attachments/assets/b3108030-24e2-46d7-be3d-68a9095d79c6"
/>
2025-09-15 16:43:52 +02:00
Charles BochetandGitHub 31d15331db Calendar month view (#14510)
<img width="1919" height="956" alt="image"
src="https://github.com/user-attachments/assets/b03509b0-6f3a-48e3-8a67-f0a9aeffe47d"
/>
2025-09-15 16:33:01 +02:00
Lucas BordeauandGitHub fc8a8dc575 Fixes to new table (#14506)
This PR brings fixes to the table after the div refactor.

There is still work to do to simplify and clean code, fix some left
bugs, but overall this PR brings a way cleaner experience already.

The table with groups still needs some work as it is often less tested,
thus it has more bugs and code to clean.

What this PR fixes : 
- Started refactoring hard-coded height and widths into constants (still
some work to do)
- Refactored TABLE_Z_INDEX and its consumer to separate into withGroups
and withoutGroups (still some refactoring to simplify this)
- Refactored common placeholder cells : add button, dynamic filling
cell, checkbox, drag and drop
- Fixed UI issues in table with groups action rows (load more and create
new)
- Started fixing z-index issues on record table with groups (some left
to do)
2025-09-15 16:28:28 +02:00
Paul RastoinandGitHub f13cbad5af View field creation through view creation unique id for migrated view (#14501) 2025-09-15 15:57:46 +02:00
c738ba54ad i18n - translations (#14503)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-15 15:38:21 +02:00
WeikoandGitHub 9853d6c095 Add fields selection in calendar view (#14500) 2025-09-15 15:28:05 +02:00
EggPuffandGitHub 0a0fb2e3b7 Fix: use <Img> instead of <object> for workspace logo in emails (#14435) 2025-09-15 15:16:14 +02:00
martmullandGitHub 57ff06f47c 1487 extensibility look into public domains to identify workspace (#14456)
- identify workspace based on public domains
- add cron job to validate public domains
- add endpoint to validate a public domain
2025-09-15 15:14:11 +02:00
c481fda0bd i18n - translations (#14499)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-15 14:43:24 +02:00
Paul RastoinandGitHub 579f704baa Plugging + improving the new orchestrator (#14430)
# Introduction
Initially this PR was about introducing integration coverage for view
field v2 tests
But feature itself wasn't finished, so ended up in a TDD style
devlopment

## The new orchestrator
Orchestrator will organize each flat entity diffing inferring either
validation errors or actions sequentially.
A new builder has been introduced when extended requires to define flat
entity validation utils and action generation for `delete` `update`
`create` operations. It's highly typed using generics

## View field integration testing
Introduce coverage on failing basic tests cases for view field
operations, successfull create is also covered. We could still add more
coverage, will be done later in following PRs

## Remaining tasks for upcoming PRs:
- [ ] rename builder methods names to add generate action in their names
- [x] refactor view validation to handle field and view uniqueness index
combination
- [ ] implem strict update validator on view and view field
- [ ] dynamic cache invalidation post run
- [ ] Add coverage to successful and failing view field operations
- [ ] error formatting summary computation
- [ ] extract types out of the workspace entity builder

## Some vision
Currently flat field metadata maps is nested in the flat object metadata
maps, making its build nested too. ( not extending the new generic
builder )
We will refactor this part for both to be stored extra flat such as the
other existing flat entities.
It will require a small refactor to the generic builder that will not
only have impact on the currently built flat entity optimistic cache but
to an other one ( for example when building a create object action it
will also have an impact flat field maps )
2025-09-15 14:32:57 +02:00
2aed7ba647 i18n - translations (#14498)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-15 14:22:53 +02:00
nitinandGitHub d1cb046ebb [Dashboards] - refactor - bar chart (#14496)
This is the first PR from the split of #14458 - refactoring only the
BarChart widget.
2025-09-15 17:52:40 +05:30
EtienneandGitHub 06605b2f36 simplify gql schema gen (#14426)
closes https://github.com/twentyhq/core-team-issues/issues/1358
2025-09-15 14:01:53 +02:00
WeikoandGitHub 1cdfc0fd62 Add calendar view layout picker in view options menu (#14495)
<img width="234" height="303" alt="Screenshot 2025-09-15 at 12 55 20"
src="https://github.com/user-attachments/assets/ac9fe1b6-4f48-4d3c-82bf-e2044f437c2e"
/>
<img width="243" height="198" alt="Screenshot 2025-09-15 at 12 55 12"
src="https://github.com/user-attachments/assets/2c23d87d-2f0b-43cc-bf79-18618fbf74d6"
/>
<img width="256" height="267" alt="Screenshot 2025-09-15 at 12 55 08"
src="https://github.com/user-attachments/assets/6a0dfc2a-8cba-46ba-bc02-a79ca621b810"
/>
2025-09-15 13:58:06 +02:00
Charles BochetandGitHub 302dd01333 Introduce RecordCard (#14497)
<img width="1919" height="956" alt="image"
src="https://github.com/user-attachments/assets/5c55af89-49b1-4173-8b52-2f02b849bc5c"
/>
2025-09-15 13:49:36 +02:00
Charles BochetandGitHub 77b6a5b29d Load data into calendar view (#14494)
<img width="1919" height="956" alt="image"
src="https://github.com/user-attachments/assets/1389b1e9-63d5-4967-9587-681d8b151b07"
/>
2025-09-15 13:09:59 +02:00
53aa60baf4 i18n - translations (#14493)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-15 11:21:17 +02:00
Charles BochetandGitHub 22bc2712ab Implement Calendar Grid (#14487)
<img width="1512" height="876" alt="image"
src="https://github.com/user-attachments/assets/bb96bc86-8ae8-4a00-b31b-cc51c43b45ef"
/>
2025-09-15 10:58:41 +02:00
WeikoandGitHub b40de0fa07 Add calendar date field picker in view options menu (#14492)
<img width="612" height="352" alt="Screenshot 2025-09-15 at 10 36 02"
src="https://github.com/user-attachments/assets/d1da5ddf-cb9a-49f2-8407-e3d22cad808b"
/>
<img width="612" height="255" alt="Screenshot 2025-09-15 at 10 35 57"
src="https://github.com/user-attachments/assets/3fca9e04-6a61-42ce-96a8-4dcd93e06f66"
/>
2025-09-15 10:58:07 +02:00
Thomas TrompetteandGitHub 155aa4995e Handle edge deletion from loop (#14489)
Update delete edge endpoint. It should handles the deletion between the
iterator and the loop step ids
2025-09-15 10:20:33 +02:00
4d2c3b7431 i18n - translations (#14488)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-15 09:32:17 +02:00
WeikoandGitHub eada8e2567 Add calendar field metadata id to view table (#14478) 2025-09-15 09:17:17 +02:00
3b0aba77ac i18n - translations (#14483)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-14 21:18:01 +02:00
469e7165fd Feat/14410 move roles tab out of all roles (#14415)
# Move the roles tabs out of All Roles section #14410

**Description:**  
This is a **draft PR** opened for early feedback before final polishing.

fixes(#14410)

**Changes included:**  
- Moved the roles tabs out of the “All Roles” section as per the Figma
design.
- Added **search functionality** to the roles sections, following the
Figma specification.
- Updated layout and components to reflect the Figma design: [Figma
link](https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=67064-202200&t=Z27CkXdNfG1vJMzG-11)

**Notes for reviewers:**  
Please provide any **recommendations, feedback, or changes** before this
is ready for final review.

---

A **screen recording** demonstrating the functionality ->

[Screencast from 2025-09-11
17-39-35.webm](https://github.com/user-attachments/assets/b1a0376e-8d12-414f-899e-83f35dd14842)
 

This is my **first contribution**, so I opened a draft PR before
polishing. Please recommend any changes and review if needed.

---------

Co-authored-by: Abdul Rahman <ar5438376@gmail.com>
2025-09-15 00:43:52 +05:30
Charles BochetandGitHub e13db84f48 Create empty page for calendar table (#14479)
<img width="1512" height="876" alt="image"
src="https://github.com/user-attachments/assets/e845fb3a-9977-4ab7-9eb7-4e60e499165b"
/>
2025-09-14 18:03:38 +02:00
e3035bd4d7 i18n - translations (#14480)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-14 17:55:18 +02:00
WeikoandGitHub a81eb854d1 Add calendar view type in picker (#14477) 2025-09-14 17:46:42 +02:00
Charles BochetandGitHub 72da21217f Deprecate ViewSort typing (#14476)
Continuing the work to deprecate the old ViewSorts and leverage types
that are available in graphql.tsx codegen as we have migrated views to
codegen
2025-09-14 17:17:35 +02:00
WeikoandGitHub f46d67f9f3 Add calendar view type (#14475) 2025-09-14 16:34:10 +02:00
Arik ChakmaandGitHub 6a96c85eed chore: upgrade tiptap to v3 (#14467)
This PR upgrades Tiptap V2 packages into V3, following their [upgrade
guide](https://tiptap.dev/docs/guides/upgrade-tiptap-v2).
2025-09-13 17:06:21 +02:00
neo773andGitHub 0c28d853e4 fix merge records network race condition (#14466)
/closes #13643

<img width="1496" height="278" alt="image"
src="https://github.com/user-attachments/assets/b10d0e8a-ff66-4046-af6a-4ff594f7ed69"
/>
2025-09-13 15:24:22 +02:00
nitinandGitHub b5809096f8 Lazy load Nivo (#14454)
oops :p
2025-09-13 15:22:43 +02:00
Saurav JainandGitHub da5ecf35fa fix: remove unused framer-motion import causing lint errors in ci (#14465)
### Summary
This PR removes an unused `view` import from **framer-motion** in
`useUpdateView.ts`.

---

### Context
- The unused import was introduced in the recent commit to `main`.
- It causes ESLint to fail, which blocks all new PRs from passing CI.

### Changes
- Removed unused `view` import from `framer-motion`.

### Impact
- Lint and CI should now pass again.
- No runtime behavior is affected.
2025-09-13 14:14:44 +02:00
Charles Bochet e08a8764f2 Fix view update 2025-09-12 23:46:17 +02:00
e2823df62f i18n - translations (#14463)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-12 23:45:49 +02:00
Félix MalfaitandGitHub a0cfff6000 Remove Luxon from codebase (#14448)
Fixes #14444 

We shouldn't have 2 libraries to manage dates, one is enough
2025-09-12 23:25:05 +02:00
Charles BochetandGitHub 1e97ad48c0 Fix on view filters (#14462)
Fixes https://github.com/twentyhq/twenty/issues/14058
2025-09-12 22:45:26 +02:00
Charles BochetandGitHub 894e599173 Fix missing relation column on tasks / notes table (#14402)
Closes https://github.com/twentyhq/twenty/issues/13484



https://github.com/user-attachments/assets/4800b25b-956d-4681-beeb-23263041fccc
2025-09-12 20:24:14 +02:00
1f333503eb Fix Entering special character in object's field name crashes the app (#14455)
Fixes https://github.com/twentyhq/twenty/issues/14289.

We should leave the error management to the form validation, and only
throw in the frame of this validation where it will be properly handled.
This is enough to prevent form submission with an undesired value.
So we can use an empty metadata name everywhere else on the page to
prevent crash.
<img width="708" height="229" alt="Capture d’écran 2025-09-12 à 17 27
51"
src="https://github.com/user-attachments/assets/f257c220-674e-49fc-b560-5ad585ae6c5f"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-09-12 20:03:55 +02:00
Charles BochetandGitHub a4cf534130 Fix View picker dropdown placement (#14457)
Fixes https://github.com/twentyhq/twenty/issues/14445

## What

In the current `MenuItemWithOptionDropdown` component (which is a
MenuItem with the 3 dots dropdown), we used to have a position: static
on the 3 dots hovered.
This enabled the dropdown to not move when we scroll the MenuItems.

However, this is not playing well with the dropdown autoplacement.
I'm removing it as I think the right solution would actually to prevent
the scroll when the dropdown is open but this is non straight forward
and not really a big issue. I'm fine with the dropdown being "fixed" to
the scrollable content, it also makes sense

Before:


https://github.com/user-attachments/assets/8efec8fa-430a-408e-b549-fd7433b7a38d

After:


https://github.com/user-attachments/assets/b8ee4375-0944-4008-9ab6-f7f9f1d67e9c



## Testing

I was considering adding a story here but this is hard to test: hover +
scroll behavior are not well supported, I don't think it worth the
investment especially as I think the vision is to block the scroll

This componenent is used in ViewPicker and MultiItemsInput (ex.
PhonesFieldInput). I have check that both were still working well
2025-09-12 19:45:23 +02:00
MarieandGitHub 89254ea9e9 Limit rest api relations depth to 1 (#14453)
Until we tackle [Implement relations depth 2 for rest
api](https://github.com/twentyhq/twenty/issues/14452), let's remove the
depth 2 query parameter which is not working (times out all the time).
2025-09-12 15:57:16 +00:00
Thomas TrompetteandGitHub 12a5ee6bc4 Add connection options on edge creation (#14451)
Edge can now be linked to loop handle.
Renaming the existing options to connection.
2025-09-12 14:08:20 +00:00
MarieandGitHub 3270c64a96 [permissions] Deprecate ObjectsPermissionsDeprecated (2/3) (#14450)
Following https://github.com/twentyhq/twenty/pull/14306 , working on the
deprecation of objectRecordsPermissions + renaming of objectPermissions
-> objectsPermissions

In this PR
- Removal of objectRecordsPermissions (was not used in the FE any
longer)
- Addition of objectsPermissions, same as objectPermission but renamed.
objectPermission is no longer used in the FE.

Next step
- Remove unused objectPermissions
2025-09-12 16:02:42 +02:00
5b9cda3341 Refactor table resize behavior (#14447)
This PR refactors table resize with the new layout using flex-wrap to
manage all the table with divs.

Due to flex-wrap, we have to manually compute some filling divs like the
last column filler div or the empty table container, otherwise the
header can wrap and display on two lines, which is the only real issue
with this implementation with wrap.

Remember that **using flex-wrap is necessary** to handle z-index as we
want for the scrolling and hovered portal cell interaction UX. Otherwise
we lose the capacity to have z-index fine-tuning on very specific edge
cases.

To handle the resize, the most performant solution was to create CSS
variables for each column width on the table, creating a class for each
column, then assigning each class to all divs that are in the same
column, using the index of the array or the fixed known position index
for that.

This PR also refactors a lot of small details around the resizing, the
naming of the component and the DX.

It notably introduces a new hook : `useHTMLElementByIdWhenAvailable`,
that is very relies on MutationObserver API to get a native HTML element
as soon as it is rendered.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-09-12 15:17:53 +02:00
nitinandGitHub 7c26b1cce3 [Dashboards] - Add seeds (#14404)
closes https://github.com/twentyhq/core-team-issues/issues/1440
2025-09-12 14:35:51 +02:00
Baptiste DevessierandGitHub fffff75156 Fix edge hovering and selection (#14416)
## Before



https://github.com/user-attachments/assets/416160bb-8289-43cb-bf0d-d2da053b2056



## After


https://github.com/user-attachments/assets/d1e3bcfc-e1cb-46d1-a7c8-9d0a32993f6d
2025-09-12 13:30:31 +02:00
MarieandGitHub e3c84f289e Fix Relation display (many side) (#14411)
Fixes https://github.com/twentyhq/twenty/issues/14280.

Imitated impementation of MultiSelectFieldDisplay.
2025-09-12 13:29:58 +02:00
martmullandGitHub b17da02ee9 Fix max-chunk-size error (#14441)
as title
2025-09-12 10:20:22 +02:00
cdaa4a0474 i18n - translations (#14440)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-12 09:45:57 +02:00
Thomas TrompetteandGitHub 231d1a98af Allow to insert into loop step ids (#14425)
- Create empty node on iterator creation
- Add options on step creation to insert in loop
- Handle properly when a step is removed from loop
- Remove loopNextStepIds from frontend action
- Add a frontend skeleton for empty action



https://github.com/user-attachments/assets/281a8c15-8062-4702-afb4-0d9a50902252
2025-09-12 07:30:28 +00:00
martmullandGitHub bdf60b1680 Fix env variable definition (#14434)
as title
2025-09-11 21:45:03 +02:00
378335a83f i18n - translations (#14432)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-11 18:35:21 +02:00
Raphaël BosiandGitHub e80c552ae7 Create the Dashboard record show page (#14423)
Closes https://github.com/twentyhq/core-team-issues/issues/1438

- Reorganized PageLayout module
- Created `DashboardRenderer` and `PageLayoutRenderer`
- Created stories for the `PageLayoutRenderer`
- Refactored the Widget components


https://github.com/user-attachments/assets/27e9ac8f-b237-4c21-8494-3fab6d65af3a
2025-09-11 18:26:26 +02:00
Paul RastoinandGitHub 140b416b22 Early throw useRecordTableRecordGqlFields.ts (#14428)
A self hoster has been facing this issue following a corrupted
`CoreView` migration
This won't fix the error but will make it more readable

Related to https://github.com/twentyhq/core-team-issues/issues/1205
2025-09-11 15:43:38 +00:00
db6e5c78ca i18n - translations (#14429)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-11 17:32:16 +02:00
Paul RastoinandGitHub c8bfbf00d7 [CoreViewField BREAKING_CHANGES] Refactor view field service v2 and resolver (#14396)
## Introduction

### Twenty-sever

Standardizing resolver input and transpilation models + return type on
destroy and delete
~~Finally~~ Did plug everything under a feature flag and add coverage
Next will do same for the view resolver and service v2

### Twenty-front
Refactored view field service in order to use codegenerated strictly
typed mutations and adapt to new api contract
2025-09-11 15:25:36 +00:00
WeikoandGitHub d9a6e7e0b1 Add flat map cache service (#14418)
## Context
Adding a new service that provides an abstract caching system for
FlatEntityMaps.
This takes care of cache invalidation and storing local and remote cache
for the map with retrieval after a comparison with map hash between
local and remote (redis).

## Implementation
Remote (redis) keys
- Flat map data:
`engine:workspace:flat-maps:{flatMapKey}:{workspaceId}:flat-map`
- Content hash:
`engine:workspace:flat-maps:{flatMapKey}:{workspaceId}:hash`

**Local Cache Hit**: If local hash matches Redis hash, return local data
**Remote Cache Hit**: If Redis has data with different hash, update
local cache
**Remote Cache Miss**: Recompute from database, store in Remote and
locally
**Invalidation**: Remove from Remote, triggering recomputation on next
access

## Usage
```typescript
@WorkspaceFlatMapCache('view') // redis key
export class WorkspaceFlatViewMapCacheService extends WorkspaceFlatMapCacheService<FlatViewMaps> {
  constructor(
    @InjectCacheStorage(CacheStorageNamespace.EngineWorkspace)
    cacheStorageService: CacheStorageService,
    @InjectRepository(ViewEntity)
    private readonly viewRepository: Repository<ViewEntity>,
  ) {
    super(cacheStorageService);
  }

  // only method to implement
  public async computeFlatMap(workspaceId: string): Promise<FlatViewMaps> {
    const views = await this.viewRepository.find({
      where: { workspaceId },
      relations: ['viewFields'],
      select: { viewFields: { id: true } },
    });

    return generateFlatViewMaps(views);
  }
}
```

```typescript
// 2 public methods, getExistingOrRecomputeFlatMaps to fetch the map and invalidateCache after a mutation 
  await this.workspaceFlatViewMapCacheService.invalidateCache(
    viewData.workspaceId,
  );

  const flatViewMaps =
    await this.workspaceFlatViewMapCacheService.getExistingOrRecomputeFlatMaps(
      workspaceId,
    );
```

## Multi-Pod Synchronization
- Each pod maintains local cache for performance
- SHA256 hash of flatMap content used for version comparison
- `invalidateCache()` reset Redis data, forcing other pods to refresh
when calling getExistingOrRecomputeFlatMaps

--- 
<img width="1072" height="325" alt="Screenshot 2025-09-11 at 15 04 48"
src="https://github.com/user-attachments/assets/ed6ce82c-db35-4a1b-8a4e-247b694e2ddf"
/>
<img width="1030" height="328" alt="Screenshot 2025-09-11 at 15 04 40"
src="https://github.com/user-attachments/assets/43a15789-7f27-4104-a9bb-bef19908a5cd"
/>

Next step: Implement a locking mechanism by reusing existing WithLock
decorator
2025-09-11 16:54:21 +02:00
a4036e0370 i18n - translations (#14417)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-11 14:43:01 +02:00
39326e6144 feat: add FormData, text, and none body types to HTTP request workflow (#14055)
This PR is a cleaned-up and improved version of #13982, excluding file
uploads for FormData.


https://github.com/user-attachments/assets/a85546f6-4e3b-4654-a4ea-e76a11016b96

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-09-11 14:32:19 +02:00
d2ebd870df i18n - translations (#14413)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-11 12:34:09 +02:00
martmullandGitHub b84f4075e5 14240 extensibility ability to create multiple custom domains for each workspace 2 (#14307)
Adds a public-domain core-module. 
Reorganize custom-domain files properly
2025-09-11 12:24:57 +02:00
nitinandGitHub ceffc82b9c [Dashboard]- Add GraphWidgetLineChart (#14386)
closes https://github.com/twentyhq/core-team-issues/issues/1371
2025-09-11 08:39:17 +00:00
Lucas BordeauandGitHub 8d10e738ac Fixed table header resize bugs (#14401)
This PR fixes the main resize bugs in
https://github.com/twentyhq/core-team-issues/issues/1453

Changes :

- A new `RecordTableResizeEffect` has been created to modify the last
column width to compensate for the resize width dynamically, because of
flew-wrap on the table elements, we cannot use width: 100% everywhere
and we have to set the width of everything.
- CSS transitions have been removed because they were degrading both the
performance and the UX when resizing
- Created a common `RecordTableHeaderCellContainer`, this was needed to
factorize the various table header components
- Created a `RecordTableHeaderLabelIdentifierCellPlusButton` component
to ease the reading of `RecordTableHeaderLabelIdentifierCell`
- Put the CSS of the blue line while resizing in the
`RecordTableHeaderResizeHandler` component to avoid duplicating it
everywhere.
- Extracted `COLUMN_MIN_WIDTH` in a constant file

Fixes https://github.com/twentyhq/core-team-issues/issues/1453
2025-09-10 17:04:47 +00:00
Thomas TrompetteandGitHub fb43827031 Add empty workflow action (#14399)
As title
2025-09-10 18:06:19 +02:00
MarieandGitHub 6895902ddf Remove Add New button when softDelete filter is present (#14385)
Closes https://github.com/twentyhq/twenty/issues/13854

In this PR
- When evaluating whether there was a soft delete filter enabled, we
were only taking into account the filter that shows all deleted records,
that can be enabled from the side panel ("See deleted records"). Now we
are also taking into account any filter on deletedAt.
- We lacked some places where we should not offer to add a new record if
a soft delete filter is on, ex on the empty page + in the kanban headers
- I decided not to add a constraint on api-side because I think there
could be use cases when importing data where we would want to be able to
create soft deleted records
2025-09-10 16:01:57 +00:00
nitinandGitHub 4239fe93b9 fix horizontal scroll caused by OTP input on 2FA settings page (#14400)
closes https://github.com/twentyhq/twenty/issues/14376
2025-09-10 17:51:20 +02:00
Félix MalfaitandGitHub 5f51d5181e Change max chunk size limit (#14398)
Deploy on main is broken, this should fix it
2025-09-10 17:28:26 +02:00
Thomas TrompetteandGitHub 3bfb5bbd86 Add duplicate step action (#14392)
https://github.com/user-attachments/assets/ac89440c-6f84-4d2a-b88a-da7ddfb181eb
2025-09-10 15:25:40 +00:00
bcf1bba302 i18n - translations (#14397)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-10 17:01:11 +02:00
WeikoandGitHub 61f1a883a0 Add workspace migration orchestrator + refactor builders + view/viewField action builders (#14383) 2025-09-10 16:55:30 +02:00
fcf3dc4429 i18n - translations (#14395)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-10 16:46:20 +02:00
Baptiste DevessierandGitHub 7b23f5ac91 Implement workflow loops default state (#14297)
https://github.com/user-attachments/assets/9176ae58-f253-469c-b5b6-98d77909db53
2025-09-10 16:32:39 +02:00
Charles BochetandGitHub 4d6ef9bc34 Implement ViewGroups optimistic rendering (#14388)
# Context

We have recently migrated from workspace.views to core.views. While
doing it, we've lost the optimistic rendering on views in frontend. This
is an issue for viewField and viewGroups that are persisted without
having an intermediate storing layer (viewFilters, viewSorts,
viewFilterGroups are not directly persisted when we do the changes,
therefore we have an underlying layer to keep them and the optimistic
was implemented there already).

ViewFields have been treated in a previous PR, this PR focus on
ViewGroups

## What
Optimistic on ViewGroups

## Other 
+ fix a bug in the sequencing to persist viewFilter + viewFilterGroups
2025-09-10 15:43:40 +02:00
Félix MalfaitandGitHub 30a2164980 First Application POC (#14382)
Quick proof of concept for twenty-apps + twenty-cli, with local
development / hot reload

Let's discuss it!



https://github.com/user-attachments/assets/c6789936-cd5f-4110-a265-863a6ac1af2d
2025-09-10 15:12:38 +02:00
Charles BochetandGitHub 9a05daa624 Fix view advanced filters broken (#14387)
## Context

We recently migrated from workspaceSchema.views to core.views. While
doing it we've migrated views using 1-5-migrate-views-to-core command
but we forgot to migrate the subFieldName

Closes: https://github.com/twentyhq/twenty/issues/14369
2025-09-10 13:59:34 +02:00
Lucas BordeauandGitHub 2044be28ec Refactored z-index handling for hovered portal with a better UX (#14384)
This PR closes the first step of
https://github.com/twentyhq/core-team-issues/issues/1451, about z-index
fine-tuning on the table.

The core part was to succeed in having the hovered portal and the
surrounding cells switch their z-index to have the borders overlap
nicely in all scrolling cases.

See associated video for the new behavior.

This PR fixes two majors UX issues we had : 
- The sticky column and row were sliding a bit on the beginning of the
scroll
- Too many components were re-rendering while we only needed to isolate
those who presented a complex use case

In the end, we isolated some very specific components like the cell 0-0
and the first scrollable header cell, which were giving the most
problems with the hovered portal.

This allows to leave the rest of the cells and header cells alone with
those concerns because they weren't involved at all in z-index update,
once we isolated those components.

## Demo



https://github.com/user-attachments/assets/cbe630ed-63c3-4e86-a22e-a11662c6082c



https://github.com/user-attachments/assets/36e6947d-9f89-4ed2-ba6c-cbb13016d7d1
2025-09-10 09:47:54 +00:00
nitinandGitHub cb0552a983 fix ci - Addd page layout rest metadata schema (#14381) 2025-09-10 11:44:38 +05:30
MarieandGitHub 5900a171f1 Enable filtering out of expected 400 errors (#14371)
We decided to send 4xx errors to sentry from the FE, except for
ForbiddenErrors.
In some cases, we also need not to send to sentry some 4xx errors, like
user input error, because the error stemming from the user input is
unpredictable (ex: duplicate entry for a record with unicity
constraints) and thus acceptable.

Let's add a isExpected extension on UserInputErrors to introduce a
specific behaviour for them (do not send to sentry).
2025-09-09 19:30:56 +02:00
nitinandGitHub 4ba1bd24f0 remove IS_API_KEY_ROLES_ENABLED feature flag (#14366) 2025-09-09 19:29:29 +02:00
Charles BochetandGitHub 002322c8e3 Rename prefetchViewStates in coreViewStates (#14373)
## Context

View system used to rely on workspaceSchema views and was loaded in what
we called the "prefetch". We have recently migrated views to
core.coreViews and the states should now be named after coreViews

Fixes: https://github.com/twentyhq/twenty/issues/14349
2025-09-09 19:11:17 +02:00
9322853641 i18n - translations (#14378)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-09 18:43:55 +02:00
Thomas TrompetteandGitHub 2b59198a1b Migrate output schema to V2 (#14311)
Previous refacto was creating output schema V2 which has more specific
schemas based on the step type. Before we were using one common schema,
which was too complex when searching for variable informations.

This PR migrate the deprecated schemas and remove the old code:
- mark previous `BaseOutputSchema` as deprecated
- remove other previous schemas
- use V2 everywhere
- icon should not be stored in schema. Instead it should be generated
based on the fieldmetadata or the item type
2025-09-09 18:37:00 +02:00
Abdul RahmanandGitHub e787dadde8 fix: agents query runs even when AI feature flag is disabled (#14372) 2025-09-09 16:07:25 +02:00
62f817b207 Added articles (pricing, onboarding, OS licence) and updated icons (#14334)
- added FAQs for several folders
- created Pricing folder, including article explaining AGPL v3 licence
- detailed settings section
- added page to give link to calendar again for onboarding call
- changed the icons - they are not necessarily relevant but at least
they are different so this remains colorful

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-09-09 15:33:02 +02:00
dc867e6e3e i18n - translations (#14370)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-09 15:01:16 +02:00
Raphaël BosiandGitHub 3d2d14eb71 Pre hook for dashboard creation + updates on the entity (#14354)
Closes https://github.com/twentyhq/core-team-issues/issues/1417

- The pre-hook creates a page-layout and links it to the dashboard
- Added `position`, `createdBy`, `attachments`, `searchVector`,
`favorites` to the dashboard entity
- Updated the view seed
- Updated the page layout services to work within a transaction
2025-09-09 12:55:22 +00:00
Paul RastoinandGitHub 861cb1c222 fix(server): morph relation fields filtering (#14365)
Tested: object metadata items retrieval and standard overrides
Please be sure to cache flush before testing this for the data loader to
be hit
2025-09-09 10:47:07 +00:00
ef68236735 fix: removes re-triggering of OTP provisioning (#14050)
Fixes : [13846 ](https://github.com/twentyhq/twenty/issues/13846)

---------

Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
2025-09-09 09:35:04 +00:00
fe27f321a9 i18n - translations (#14362)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-09 10:49:09 +02:00
EtienneandGitHub 719be52b53 Upsert - fixes (#14358)
- add more explicit error message on upsert conflicts
- increase MAX_RECORDS_QUERY constant
- add soft deleted records when returning upserted records




fixes https://github.com/twentyhq/private-issues/issues/300
2025-09-09 08:44:07 +00:00
Thomas TrompetteandGitHub 7094f0ee08 Remove is branch enabled feature flag (#14357)
As title
2025-09-09 10:07:20 +02:00
Paul RastoinandGitHub 7bcbaee0c8 Fix get time on non date var (#14361) 2025-09-09 09:59:55 +02:00
f7cde28dd6 🔧 Restore PRs #14348 and #14352 that were reverted by PR #14347 (#14359)
## Problem

**CRITICAL:** Two PRs were accidentally reverted when PR #14347 "Prevent
csv export injections" was merged:

1. **PR #14348** "[Page Layout] - Review Refactor" -  **RESTORED**
2. **PR #14352** "Fix wrong path used by backend" -  **RESTORED**

## Root Cause Analysis

During the merge of PR #14347, there was a complex merge conflict with
PR #14352 "Fix wrong path used by backend". The merge commit
`324d7204bb` in the PR #14347 branch brought in changes from PR #14352,
but during the conflict resolution, **BOTH PR #14348 and PR #14352's
changes were accidentally overwritten**.

## What This PR Restores

This PR restores **BOTH** PRs by cherry-picking their commits:

###  PR #14348 Changes Restored:
- `GraphWidgetRenderer.tsx` - was deleted, now restored
- `WidgetRenderer.tsx` - was missing, now restored  
- `SettingsPageLayoutTabsInstanceId.ts` - was deleted, now restored
- `useUpdatePageLayoutWidget.ts` - was renamed back, now restored with
correct name
- Multiple test files that were deleted
- Several hook files that were renamed/reverted
- File renames: `usePageLayoutWidgetUpdate.ts` →
`useUpdatePageLayoutWidget.ts`
- Hook refactoring and test file organization
- Page layout component improvements

###  PR #14352 Changes Restored:
- **Types moved to twenty-shared:**
  - `packages/twenty-shared/src/types/AppBasePath.ts`  RESTORED
  - `packages/twenty-shared/src/types/AppPath.ts`  RESTORED
  - `packages/twenty-shared/src/types/SettingsPath.ts`  RESTORED
- **Navigation utilities moved to twenty-shared:**
- `packages/twenty-shared/src/utils/navigation/getAppPath.ts`  RESTORED
- `packages/twenty-shared/src/utils/navigation/getSettingsPath.ts` 
RESTORED
- **200+ import statements updated** across the codebase to use
twenty-shared
- **Old type files deleted** from twenty-front/src/modules/types/

## Evidence of Complete Restoration

**Before (reverted state):**
-  Types were in `packages/twenty-front/src/modules/types/`
-  Page layout files missing
-  Hook files incorrectly named

**After (this PR):**
-  Types correctly in `packages/twenty-shared/src/types/`
-  All page layout files restored
-  Hook files correctly named
-  All import statements updated

## Verification

**Total changes:**
- PR #14348: 36 files changed, 863 insertions(+), 442 deletions(-)
- PR #14352: 243 files changed, 492 insertions(+), 461 deletions(-)
- **Combined: 279 files changed, 1355 insertions(+), 903 deletions(-)**

## Impact

This completely restores both PRs that were accidentally lost, ensuring:
1. Page layout refactoring work is back
2. Type organization and path utilities are correctly in twenty-shared
3. Backend email paths work correctly again
4. No functionality is lost

Fixes the reversion caused by the merge conflict in PR #14347.

---------

Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
2025-09-08 21:48:13 +02:00
Paul RastoinandGitHub ebc48e3bb2 Remove unused utils from v2 (#14356) 2025-09-08 18:16:50 +02:00
cebcf4f1f5 Prevent csv export injections (#14347)
**Small Security Issue:** CSV exports were vulnerable to formula
injection attacks when users entered values starting with =, +, -, or @.
(only happens if a logged-in user injects corrupted data)

Solution:
- Added ZWJ (Zero-Width Joiner) protection that prefixes dangerous
values with invisible Unicode character
- This is the best way to preserve original data while preventing Excel
from executing formulas
- Added import cleanup to restore original values when re-importing
 
Changes:
- New sanitizeValueForCSVExport() function for security
- Updated all CSV export paths to use both security + formatting
functions
- Added comprehensive tests covering attack vectors and international
characters
- Also added cursor rules for better code consistency

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-09-08 17:57:46 +02:00
nitinandGitHub 374b5dce66 Fix REST API view name template replacement (#14244)
REST API was returning raw template strings like 'All
{objectLabelPlural}' instead of replaced values. GraphQL had proper
handling but REST controllers don't have access to DataLoaders.

Added minimal template replacement using WorkspaceMetadataCacheService
to replace {objectLabelPlural} placeholders with actual object labels.
No full translations since REST isn't priority for i18n.

addressing -
https://discord.com/channels/1130383047699738754/1412122807281651833
2025-09-08 17:51:30 +02:00
ad944e1d2c merge records composite type (#14005)
/closes #13989

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-09-08 17:50:26 +02:00
Paul RastoinandGitHub 9e81618773 Refactor morph field name and morph data loader (#14299)
# Introduction
Storing morph relation field names directly in database, using morphId
to aggregate them
Removing dynamic morph field metadata computation in schemas and data
loader

Will add integration tests on morph data loader entry

closes https://github.com/twentyhq/core-team-issues/issues/1425 
closes https://github.com/twentyhq/core-team-issues/issues/1424 
closes https://github.com/twentyhq/core-team-issues/issues/1423
2025-09-08 17:20:18 +02:00
Raphaël BosiandGitHub 49ee73a16c Update open api with page layout (#14355)
Closes https://github.com/twentyhq/core-team-issues/issues/1396
2025-09-08 17:19:06 +02:00
Charles BochetandGitHub a758154690 Add clean workspace cron command (#14353) 2025-09-08 16:46:31 +02:00
Félix MalfaitandGitHub 502bd07db9 Fix wrong path used by backend (#14352)
After moving a section on the frontend, this broke the path that was
sent by email on the backend.
This kind of error comes back every ~2-3 month under different forms so
we need a more robust solution: I moved routes to the shared folder,
that way we will share one common source of truth between the frontend
and the backend.

Fixes #14343
2025-09-08 16:07:13 +02:00
nitinandGitHub 894db2645a [Page Layout] - Review Refactor (#14348)
addressing the review on
https://github.com/twentyhq/twenty/pull/14318#pullrequestreview-3191930203
2025-09-08 12:20:43 +00:00
Lucas BordeauandGitHub 8fa1821e1a Refactored table body and footer with divs (#14346)
This PR refactors what is remaining of HTML table API to divs.

It is mainly about the body and aggregate footer.

Because a `position: sticky` creates a stacking context, and because a
div wrapping other divs prevents those children divs from being sticky,
it has been found that removing the wrapping container of both header
and footer allows us to have all z-index in the same stacking context
and create the right experience.

Though the fine-tuning of z-index will be done in another PR.

There are many fixes left that will be addressed very soon in subsequent
PRs.

This PR focuses on bringing a functional table both with and without
RecordGroups. (Check Task views for that)
2025-09-08 12:13:50 +02:00
Charles BochetandGitHub 9fe88c2639 Messaging cleaning fixes (#14345) 2025-09-08 00:25:45 +02:00
ab49a22b45 fix : Check double-click behavior when entering 2FA code (#14286)
disable the button when a request is in progress. 

Fixes #14278

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-09-07 22:10:22 +02:00
Charles BochetandGitHub f9677122b6 Improve Messaging Gmail experience (#14342)
In this PR, I'm solving several issues:
1) We were not checking if the currentWorkspaceMember was owning the
message in the thread. It kind of worked before because the case of
shared threads (with shared threads visibility restriction) was not
happening that often. It seems that the bug has always been there
2) Re-implement orphan messages and threads deletion on messageChannel
deletion. We used to brutally look for all orphans, we disabled it last
week because it was too heavy on db. I've re-implemented it more
carefully and "surgically"
3) Gmail sync was not handling folder synced correctly. It was
leveraging labelIds which it shouldn't do (this is a AND AND parameter)
in full sync
4) Added a command to clean orphan message threads manually if needed.
Usually this is done when you remove a messageChannel, or change
blocklist rules but it can be useful to have it to debug
2025-09-07 20:36:28 +02:00
b78d139db5 fix: Server-level impersonation doesn't bypass 2FA when enabled (#14340)
## Description

- This PR solves the a sub-issue from
https://github.com/twentyhq/core-team-issues/issues/1421
- impersonation tokens bypasses 2FA as intended 
- Added Audit trails to cover all impersonation events
- Added Proper testing coverage

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-07 15:53:23 +02:00
Andrey AdamovichandGitHub 214375556a Fix typo in header (#14337) 2025-09-06 12:53:38 +02:00
5d6b5560e6 i18n - translations (#14336)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-06 11:37:40 +02:00
nitinandGitHub ab9b5ca4c5 [Page Layouts] - Add tabs (#14318) 2025-09-06 11:27:37 +02:00
Lucas BordeauandGitHub 821ae7c60d Refactor table header with divs (#14319)
Fixes https://github.com/twentyhq/core-team-issues/issues/1432

We still have some follow-up issues here, I only took care of making the
essential of the table work, but the follow-up issues will be better
tackled after everything has been switched to div, otherwise we might
fix them multiple times.

A first round of refactoring of z-index has been made in a common
constant, where it is easier to understand, for which case, what should
be the order of the different layers.

Though we still need to have another round of refactor because of the
stacking contexts, mainly because of the header row that is creating a
stacking context that makes it hard to have all scrolling cases work.
2025-09-05 18:54:38 +02:00
Thomas TrompetteandGitHub e8511a4da0 Fix flaky test (#14331)
Test was failing the 15th of each month
2025-09-05 18:50:07 +02:00
Charles BochetandGitHub 286682c197 DevXP improvements on new views (#14330) 2025-09-05 18:49:20 +02:00
Félix MalfaitandGitHub 4c4811dca7 Fix broken unit test after translation was added (#14329)
1-line fix, test is wrong since Lingui translations have been corrected
now
2025-09-05 17:53:00 +02:00
Raphaël BosiandGitHub 9445256eee Create PageLayoutWidget resolver and controller (#14315)
Closes https://github.com/twentyhq/core-team-issues/issues/1395
2025-09-05 16:59:51 +02:00
Charles BochetandGitHub f802294c84 Improve upgrade command and prepare 1.5 release (#14325)
In this PR:
- refactor the upgrade command / upgrade command runner to keep upgrade
command as light as possible (all wrapping logic should go to upgrade
command runner)
- prevent any upgrade if there is at least one workspace.version <
previsousVersion ==> this leads to corrupted state where only core
migrations are run if the self-hoster is skipping a version
2025-09-05 15:58:17 +02:00
d5ef4cbbff i18n - translations (#14326)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-05 14:22:37 +02:00
22157be640 i18n - translations (#14324)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-05 14:12:26 +02:00
3bc86cdc10 i18n - translations (#14321)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-05 12:46:05 +02:00
Félix MalfaitandGitHub d5f88e566c Get ready for 1000+ members (#14313)
The goal of this PR is to test if Twenty can support a large number of
members, a question which was raised by a large company that is
considering moving away from Salesforce.

I was expecting the currentWorkspaceMembersState to cause a lot more
issue. It would be very hard to get rid of it in the context of actors,
I think that would require a big refactoring. I thought we'd have to do
it but it turns out the perf are pretty good. One thing we need to
improve is the pagination on the roles page, we'll wait for @Bonapara to
update that
2025-09-05 12:37:22 +02:00
094d670590 i18n - translations (#14320)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-05 12:20:51 +02:00
Paul RastoinandGitHub 17c646f9d8 Fix views integration tests (#14317)
Following https://github.com/twentyhq/twenty/pull/14202
2025-09-05 10:16:40 +00:00
5824637d1a fix - newly added object not visible in left menu (#14202)
resolves #14190 

added refreshCoreViews() call after object creation to immediately
update core views state, ensuring new objects appear in the navigation
drawer without requiring a refresh

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: prastoin <paul@twenty.com>
2025-09-05 10:43:03 +02:00
Raphaël BosiandGitHub 9746c3a787 Create PageLayoutTab resolver and controller (#14284)
Closes https://github.com/twentyhq/core-team-issues/issues/1394
2025-09-04 16:07:33 +00:00
0f806126ac i18n - translations (#14309)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-04 17:33:47 +02:00
7a999c8476 Format date displayed in Releases section (#14183)
Closes #14177 

I noticed a `formatDisplayDate` file being used in `twenty-website` and
created the same one for `twenty-front` as well. Unit tests for the same
have been added.

<img width="1438" height="770" alt="image"
src="https://github.com/user-attachments/assets/5aa6eef5-19c5-4108-bf3f-c582d0ca1b59"
/>
<img width="1275" height="785" alt="image"
src="https://github.com/user-attachments/assets/20a87ba6-fca4-472c-a691-362901505303"
/>

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-04 17:27:31 +02:00
MarieandGitHub 40251d34ec [permissions] Deprecate ObjectsPermissionsDeprecated (1/3) (#14306)
We want to update UserWorkspacePermissions from 
```
export type UserWorkspacePermissions = {
  permissionFlags: Record<PermissionFlagType, boolean>;
  objectRecordsPermissions: Record<PermissionsOnAllObjectRecords, boolean>;
  objectPermissions: ObjectsPermissionsDeprecated;
};
```

to
```
export type UserWorkspacePermissions = {
  permissionFlags: Record<PermissionFlagType, boolean>;
  objectsPermissions: ObjectsPermissions;
};
```

`ObjectsPermissionsDeprecated` and `ObjectsPermissions` are actually
very similar, they only have different key names (`canRead` vs
`canReadObjectRecords`)

To avoid brutal breaking changes, we will proceed in multiple steps: 

1. This PR: adapt FE so it does not call objectRecordsPermissions
anymore + add the new objectsPermissions to UserWorkspacePermissions
without calling it yet in the FE
2. Remove objectRecordsPermissions in BE + use objectsPermissions in FE
instead of objectPermissions
3. Remove objectPermissions
2025-09-04 14:03:33 +00:00
StephanieJoly4GitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
5c1ce8476d Updating the user guide (#14308)
- reorganized folders
- corrected typos
- added file to give advices regarding the data model creation

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-09-04 16:00:57 +02:00
Thomas TrompetteandGitHub d6ba6a66a4 Restrict workflow object permissions (#14290)
- workflows should not edit system objects or workflow related objects
- system fields should be usable within variables for reading
2025-09-04 10:39:51 +02:00
6e570ba6c8 i18n - translations (#14295)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-04 05:37:32 +02:00
Abdul RahmanGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
79bcd90d8d Feat: role applicability controls (#14239)
Closes [#1404](https://github.com/twentyhq/core-team-issues/issues/1404)

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-09-04 08:58:50 +05:30
MarieandGitHub 052f91cff1 Adapt field permissions to label identifier (#14287)
Closes https://github.com/twentyhq/core-team-issues/issues/1316

As discussed with @Bonapara, the behaviour is the following:

1 if there is a read restriction on a field that is or becomes the label
identifier, this restriction is actually overriden to allow any user who
has read rights on the object to also be able to read the values on the
label identifier field. This restriction is overriden in the values
stored in the cache but not in the db.
2 in the UI it is not possible to add a field permission to restrict
read rights on the field that is the label identifier. It is still
possible to update the label identifier for it to be a field that
previously had a restrictive field permission on a role though, but then
1. has our back.
2025-09-03 19:37:06 +02:00
Paul RastoinandGitHub 4fa114b3ec Add MorphId column to MORPH_RELATION field metadata (#14285)
close https://github.com/twentyhq/core-team-issues/issues/1426
2025-09-03 18:33:17 +02:00
11fd01eaa4 i18n - translations (#14288)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-03 17:46:04 +02:00
nitinandGitHub 0a6d5479c9 [Dashboards] - add iframe widget (#14251)
closes https://github.com/twentyhq/core-team-issues/issues/1415
2025-09-03 17:31:38 +02:00
Thomas TrompetteandGitHub 7ac7f52510 Remove all saves from workflows (#14283)
- replace save by insert
- if the insert output is needed, cast the generatedMaps
- remove transactions from trigger services. Doing it manually would be
complex and not reliable
2025-09-03 15:41:03 +02:00
EtienneandGitHub 6ee41f33c6 fix - remove Untitled default value on standard name field (#14282)
Enable unique constraint creation on name standard field. 
Null values are handled in front with 'Untitled'.

Need to migrate fieldMetadata default value on all custom objects ?

Tested : 
- Toggle on/off uniqueness on standard name field of standard/custom
object
- Create new custom text field and toggle on/off uniqueness
2025-09-03 14:45:34 +02:00
7e7837abf3 Fixed aggregate footer not displayed (#14276)
This PR fixes a bug that made the aggregate footer not displayed.

It was because of a wrong filter on `visibleRecordFields` array.

Follow-up of https://github.com/twentyhq/twenty/pull/14048

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-09-03 13:54:44 +02:00
EtienneandGitHub 6644957aca Fix - ChipField display in settings data model (#14277)
labelIdentifier fields display throw error in settings data model (field
settings and object settings)

To reproduce, go to /settings/objects/companies/name or
/settings/objects/companies#settings
2025-09-03 13:12:29 +02:00
c943480791 i18n - translations (#14279)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-03 12:20:36 +02:00
Paul RastoinandGitHub 6522498df0 Failing morph relation creation v2 integration testing & fixes (#14253)
# Introduction
closes https://github.com/twentyhq/core-team-issues/issues/1408
2025-09-03 12:14:43 +02:00
Thomas TrompetteandGitHub 2e7fe238ed Clean step and edge errors (#14261)
- add filters for both resolvers
- map to gql errors

Should fix https://github.com/twentyhq/core-team-issues/issues/996
2025-09-03 10:00:02 +02:00
Charles BochetandGitHub c847a72926 add logs to fix note target creation (#14268) 2025-09-03 08:11:03 +02:00
WeikoandGitHub ee7aec7447 fix auth context injection (#14266) 2025-09-02 23:11:00 +02:00
WeikoandGitHub 18d6fd2f71 fix rest API tests (#14265) 2025-09-02 23:01:27 +02:00
WeikoandGitHub 1eeca13458 Fix transactions within rest + limit (#14264) 2025-09-02 21:54:43 +02:00
89c620ee52 i18n - translations (#14263)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-02 19:01:04 +02:00
martmullandGitHub 7c195b3bfd Reorganize files properly (#14262)
just code reorganization
2025-09-02 16:56:34 +00:00
Thomas TrompetteandGitHub b0c76c799c Improve workflow queue jobs (#14259)
- move cron commands logic to a workspace service
- add commands to enqueue not started and dequeue staled workflows
- stop dispatching one job per workspace. Handle all workspaces in one
job
- run enqueue cron every 5 minutes instead of every minutes

Follow up:
- add a separated redis key to control if there are not started
workflows. It will avoid fetching workflow runs for each workspace
2025-09-02 14:51:40 +00:00
martmullandGitHub aae99482a1 Remove workspaceId from path parameter for route endpoints (#14258)
- remove workspaceId from path parameter for route endpoints
- use host to infer workspaceId
2025-09-02 16:38:29 +02:00
Raphaël BosiandGitHub fed09339f6 Create PageLayout resolver and controller (#14219)
Closes https://github.com/twentyhq/core-team-issues/issues/1393
2025-09-02 16:12:18 +02:00
Charles BochetandGitHub 92c27b337a Fix view creation (#14254) 2025-09-02 15:07:15 +02:00
1652cd8815 i18n - translations (#14255)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-02 14:43:37 +02:00
1801b5086a Remove subscriptions job (#14250)
Remove subscriptions publish job

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-09-02 14:40:30 +02:00
c613bdc238 i18n - translations (#14252)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-02 14:22:50 +02:00
EtienneandGitHub 447892b7ef fix - update error message and ease importable format for multi select (#14203)
- Add other string format ('option1,option2,..') for multi select import
- Update error message


closes : https://github.com/twentyhq/twenty/issues/14103
2025-09-02 12:18:45 +00:00
Paul RastoinandGitHub 6d6ee939cf Morph relation field v2 fixes (#14216)
Fixes, depending on the contextual current operation in order to
retrieve relation target and all morph related fields to be delete:
- DELETE Field,
- DELETE Object, 
- UPDATE Field, that affects all others related fields
2025-09-02 12:17:20 +00:00
nitinandGitHub c4f56156d6 Translations - FIX - views not being refreshed on locale change (#14207)
as per title
2025-09-02 14:00:40 +02:00
WeikoandGitHub ce3fcb295d Add traces to transaction rollback exceptions (#14246) 2025-09-02 13:58:37 +02:00
WeikoandGitHub 9ad476c6bb Fix dataloader service not provided in core graphql config (#14248)
## Context
Views and some other objects "leak" in the core API, this should be
fixed but in the meantime they fail if they use dataloaders because it's
not provided in the core config

```
  [
    TypeError: Cannot read properties of undefined (reading 'objectMetadataLoader')
  ]
  ```
in view.resolver using dataloaders to compute the name field

How to test: query views from /graphql instead of /metadata

Note: we could have a dedicated dataloader service for each gql server in the future
2025-09-02 13:17:59 +02:00
2bf246186a i18n - translations (#14245)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-02 12:35:25 +02:00
nitinandGitHub 1b2f079359 Page Layout - Addition of widgets (#14184)
https://github.com/user-attachments/assets/130f12d7-5cef-4b83-912f-a9d42241f69f

~~This could be considered a POC 😅~~

addressing - 
https://github.com/twentyhq/core-team-issues/issues/1400
https://github.com/twentyhq/core-team-issues/issues/1403
2025-09-02 10:20:28 +00:00
EtienneandGitHub 04d4c07b69 fix - use createMany service in createOne one (#14208)
closes : https://github.com/twentyhq/twenty/issues/14072
2025-09-02 11:40:43 +02:00
martmullandGitHub a722d97724 14066 extensibility add coretriggerroute table (#14241)
This Pr 
- adds a `route` table to the core schema
- adds a controller to trigger route

For now, we need to add a `/s/<workspace_id>` prefix to all routes

We plan to create a custom domain table in order to let the users create
subdomains for their workspace, and so to link their routes to a
subdomain. Thank to that, we will be able to identify workspace_id from
domain name, and the prefix could be `/s`. If we create a native
dedicated subdomain for routes for each workspaces, the prefix could be
completely removed!

Here the follow up ticket to do that ->
https://github.com/twentyhq/twenty/issues/14240
2025-09-02 11:24:59 +02:00
Lucas BordeauandGitHub bfad5b0477 Cleaned FieldDefinition props and removed recoil calls (#14220)
This PR removes some unused props from FieldDefinition type and put some
recoil calls higher up in the hierarchy.

This PR fixes a regression on Chip introduced by
https://github.com/twentyhq/twenty/pull/11498, where we don't want
"Untitled" to be displayed in compact mode.

# FieldDefinition refactor

Removed `isLabelIdentifierCompact` and `labelIdentifierLink` which can
be derived directly in the chip component or computed in the record
table context.

Removed `disableTooltip` and `infoTooltipContent` because they were not
used.

Introduced `fieldMetadataItemId`, as optional for now, to have the
ability to progressively refactor the different things that could be
derived from this and `recordId`.

# Performance improvements

There's not a great deal to be gained for now on those modifications,
which specifically concern the identifier column.
2025-09-02 08:49:55 +00:00
Raphaël BosiandGitHub 90432f5b13 Fix dashboard seeding (#14218)
Fix dashboard seeding
2025-09-02 10:22:12 +02:00
Paul RastoinandGitHub da288b1998 V2 integ test sequential operations testing (#14228)
Wil need to add a morph relation field in a new test suite
Especially searching for enum collision
2025-09-02 10:15:01 +02:00
neo773andGitHub a7a79090cb fix: QueryRunner overrideDataByFieldMetadata sub fields not being stringified (#14187)
Adding `secondaryLinks` to company is broken, this fixes it

Regression can be traced back to this commit
https://github.com/twentyhq/twenty/pull/10912/files#diff-8a992c6bff80abc8c9075d585d293f6aa98c246df097efb4f904b82dc3ff8114R210-R214



https://github.com/user-attachments/assets/463cee62-8ee3-45dc-9912-fd8fb5244579
2025-09-02 10:05:42 +02:00
Baptiste DevessierandGitHub d94e984a80 Render WorkflowActionMenuItems as a proper component (#14223) 2025-09-02 09:53:25 +02:00
WeikoandGitHub 866d8bc0ca Implement workspace datasource destroy for pg pool (#14232) 2025-09-01 20:54:45 +02:00
d4ee2b6098 i18n - translations (#14225)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-01 19:00:58 +02:00
2af0e890b2 i18n - translations (#14224)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-01 18:47:44 +02:00
Thomas TrompetteandGitHub bcd5cf7f25 Add first frontend version for iterators (#14213)
Add a base for testing iterator step in frontend. Loop next step ids
need to be added to an input since the loop handle does not exist on the
step yet.

Here is an example of run:
<img width="1271" height="653" alt="Capture d’écran 2025-09-01 à 16 21
39"
src="https://github.com/user-attachments/assets/06ecf981-be17-4d31-84f6-11c2cc98cb66"
/>

First create record in the loop name is `{{currentItem}} - first`, the
second is `{{currentItem}} - second`
<img width="276" height="326" alt="Capture d’écran 2025-09-01 à 16 22
25"
src="https://github.com/user-attachments/assets/0ae03b65-aeda-41a6-8693-c17711ec2102"
/>
2025-09-01 16:46:33 +00:00
MarieandGitHub 0d5fedfb0a Fix user friendly message for non available object name (#14210)
Fixes https://github.com/twentyhq/twenty/issues/13577.

When naming or renaming an object, we are already checking that the name
was available compared to other existing objects.
But we also need to check that the relation fields that will be created
or updated are available as well: we create relation fields on
Attachment, Note, Favorite, Task and TimelineActivites, that bear the
name of the object. Thus, it is not possible to create an object that
has the same name as one of the fields on Attachment, Note etc: name,
createdAt, ... are not valid names.
2025-09-01 16:35:40 +00:00
Abdul RahmanandGitHub 3f7f78eef8 fix: workflow run page crash (#14222)
Closes [#292](https://github.com/twentyhq/private-issues/issues/292)

Before:


https://github.com/user-attachments/assets/848df76f-c2fb-46c8-b70a-4ec990f2917c



After:


https://github.com/user-attachments/assets/60aa83b0-84ab-477c-ad79-b88a43ad7fa8
2025-09-01 18:29:29 +02:00
Baptiste DevessierandGitHub 3587d0ae00 Don't select node when clicking on Add Step button container (#14211)
## Before



https://github.com/user-attachments/assets/74ab75a3-adc7-40fa-be18-d39ec8092fa5



## After



https://github.com/user-attachments/assets/aae66441-b702-4c41-9c19-45b7384cf90f
2025-09-01 17:13:25 +02:00
Thomas TrompetteandGitHub 2af611e938 [Iterator] Implement Backend for Iterator step (#14145)
Manually tested by starting to implement the frontend:
- loopStepIds contains a create record action that takes one item at a
time
- items to iterate are a list of string that will be used as record
title


https://github.com/user-attachments/assets/728310d9-4728-422f-a324-3783da24e517
2025-09-01 16:00:26 +02:00
Charles BochetandGitHub 22a200171e Fix view performances (#14209) 2025-09-01 15:24:30 +02:00
Antoine MoreauxandGitHub 98de9259eb fix(billing): retain original casing for event_name in Stripe meter… (#14204)
…ed event creation
2025-09-01 13:38:03 +02:00
WeikoandGitHub 80347b7b38 Rename uniqueIdentifier to universalIdentifier (#14201) 2025-09-01 12:33:59 +02:00
Paul RastoinandGitHub 58a38769bd Morph relation v2 schema runner (#14195)
close https://github.com/twentyhq/core-team-issues/issues/1410
2025-09-01 11:39:06 +02:00
WeikoandGitHub aa3e21a243 Add query timeout to core datasource (#14197) 2025-09-01 11:15:51 +02:00
Charles BochetandGitHub 988f6ee1fa Remove old view implementation step 1 (#14189)
Let's move forward and get rid of the past... !

Removing prefetchViewState and the prefetch view query.

Next steps:
- renaming Selectors to remove prefetch keywork
- remove old view type and coreViewToView util
- rework optimistic rendering for coreViews
2025-09-01 10:25:16 +02:00
Charles BochetandGitHub 1e9723a6b7 Fix workspace deletion broken (#14188)
Workspace deletion was broken because workspace schema deletion should
be "CASCADE". Otherwise postgres will refuse to remove a schema with
existing tables

Also, user experience on delete was degraded because of redirect race
condition:
- we were redirecting to /welcome on deletion
- also redirecting to /settings/profile as the system detects
missingPermissionFlag

I'm disabling permission check if the user is not logged in as it does
not makes sense. I don't think this is a big issue but we will likely
revisit this later if we face race condition between Permission checks
redirect and PageChangeEffect. This could also be migrated fairly easily
to PageChangeEffect where we make sure that we only redirect once
2025-08-31 18:59:51 +02:00
fb3341dd9c i18n - translations (#14182)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-30 17:46:04 +02:00
neo773GitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
8ab71fef1f feat: message folders control (#14144)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-08-30 17:39:10 +02:00
a0884cede9 i18n - translations (#14181)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-30 17:20:02 +02:00
Charles Bochet f8324160a6 Add core view syncing enabled by default for new workspaces 2025-08-30 17:07:52 +02:00
d87eaa141e i18n - translations (#14179)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-30 17:07:07 +02:00
2043694a8f i18n - translations (#14178)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-30 17:01:10 +02:00
Félix MalfaitandGitHub 50521dec34 Revamp settings navigation (#14174)
Menu was getting too long so I'm removing the developer section and
merging API+Webhook together (in the past we had made a split partially
because it was in the advanced mode), I'm also merging Lab and Releases.
I'm moving Approved Domains and Workspace Domain to a new dedicated
page, which will also hold email domains by end of year, because it
makes sense to do all those at once (involve DNS changes).
2025-08-30 14:43:04 +00:00
Charles BochetandGitHub d570ab05e6 Fix billing translations (#14176) 2025-08-30 16:29:43 +02:00
Charles BochetandGitHub f597c93533 try trigger translations (#14175) 2025-08-30 16:18:41 +02:00
9e4e8009d7 i18n - translations (#14172)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-30 14:42:31 +02:00
Charles BochetandGitHub cef476cd76 Add logs to worker job handling (#14171)
I'm troubleshooting queue worker getting stuck on production and I
suspect a particular job to be the root cause. However I can pinpoint
which one it is. Adding this logs will be helpful to troubleshoot
2025-08-30 14:08:30 +02:00
Antoine MoreauxandGitHub dfa73e9e7a chore(billing): comment out unused metered billing references in Sett… (#14170)
…ingsBillingCreditsSection
2025-08-30 12:01:49 +00:00
db5897d4d0 Refactor board field definitions to use record fields (#14165)
This PR removes board field definitions usage in favor of record fields,
like we've already done on table with table columns.

This PR also introduces a first step in the refactoring of the
RecordIndexContext as a new way to store in-memory a normalized cache
for some states used pretty much everywhere like field metadata items or
field definition (for now but it will soon be removed).

Since most of those states do not change if we don't modify the
metadata, then we can safely store them in a context, which has the
fastest access time in React.

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-30 13:36:28 +02:00
nitinandGitHub 74eeb98293 Page Layout Initialization on Settings (#14156) 2025-08-29 20:50:23 +02:00
Charles BochetandGitHub a132a0e88b Core view migration fixes (#14166)
Bugs found with feature flag IS_CORE_VIEW_ENABLED:
- Switching a view type does switches but does not update the option
dropdown selected menu item, we have to refresh ==> **fixed**
- Reordering a field in the option dropdown causes a bug because it
tries to update with a decimal position like 1.5 but the position field
on core views is integer ==> **fixed**
Hidding a field triggers the update, but making it visible again right
after that does not trigger the DB update, we have to refresh the app
==> **not fixed, medium bug**
Reordering core view groups in option dropdown fails ==> **fixed**
Showing / hidding core view groups fails ==> **fixed**
Creating a table group view works but if we select kanban right after it
fails ==> **fixed**
Move right / move left on kanban core view group doesn’t do anything ==>
**fixed**
Deleting a view from the view dropdown fails ==> **fixed**
Creating a view from another view does not copy the view groups ==>
**not fixed, medium bug**
Move left / right has a strange behavior, not working consistently, it
sends always the same position ==> **not fixed, medium bug**
View re-order optimistic update is broken, but the DB update works ==>
**now it's dancing not fixed, medium bug**


Next steps:
- we should re-work the optimistic behaviors of view updates but let's
clean the code first
2025-08-29 20:01:12 +02:00
Charles BochetandGitHub c1870c3990 Enable CoreView feature flag on new workspaces (#14164) 2025-08-29 19:07:07 +02:00
Vicky WangGitHubvickywxngCharles Bochetgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
e142663dec v1.4 Release Note (#14161)
## Summary
- Added release note for Field Level Permissions, 2-Factor
Authentication, and Workflow Filters
- Uploaded the according covers

---------

Co-authored-by: vickywxng <vw92@cornell.edu>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-08-29 19:03:48 +02:00
Charles BochetandGitHub 7c96a6be32 Fix migrate view migrate command (#14163) 2025-08-29 18:53:42 +02:00
WeikoandGitHub 316055be64 Replace view tables position columns from integer to double (#14162) 2025-08-29 18:39:11 +02:00
Antoine MoreauxandGitHub 1c4568c8b1 feat(pricing/ai): improve billing metered pricing + add pricing on ai chat (#14092)
## TODO:

- [x] display "yearly" or "monthly" wording everywhere it's needed
- [ ] Add button with "downgrade" or "upgrade" to save the change of
credits price + modal to validate
- [x] Add renewal date 
- [ ] Implement
https://docs.stripe.com/billing/subscriptions/subscription-schedules for
`switchFromYearlyToMonthly` and decrease number of credits
2025-08-29 16:23:07 +00:00
Paul RastoinandGitHub 7df9094939 RelationFieldMetadataType to MorphOrRelationFieldMetadataType and so on (#14160) 2025-08-29 15:25:12 +00:00
Paul RastoinandGitHub a2296c02ec Delete morph v2 adjustements (#14158)
we need to handle both:

- morph relation field deletion ( implies every related morph and target
deletion )
- target RELATION only the pair that could contain a morph or not we
don't care


close https://github.com/twentyhq/core-team-issues/issues/1411
2025-08-29 17:11:59 +02:00
Charles BochetandGitHub a2114fbcf9 Fix migrate view importing viewFilterGroups before viewFilters (#14159)
As per title
2025-08-29 17:04:32 +02:00
Paul RastoinandGitHub 6397a4d906 Update object handle morph join col rename (#14153)
# Introduction
When udpating a flat object metadata name we need to search for RELATION
field that has a MORPH RELATION target flat field metadata with
MANY_TO_ONE relationType as its settings are binded to the updated flat
object metadata name

In the best of the world we would remove this complexity to be computed
at runtime only and deprecate implemented logic here

close https://github.com/twentyhq/core-team-issues/issues/1412
2025-08-29 16:46:15 +02:00
Charles BochetandGitHub 28f1481d15 Improve migrate view to core command to sanitize existing resources (#14157)
Cleaning the viewFields, viewSorts, viewGroups and viewFilters that do
not have fieldMetadataIds before migrating them
2025-08-29 16:39:16 +02:00
Charles BochetandGitHub 1607f5ab41 Add dagrejs on server (#14152) 2025-08-29 15:17:53 +02:00
GuillimandGitHub f6843fcdef Seed morph metadata (#14149)
in thie PR we create the tooling to allow the relation and morph
relation creation during the seed process.

We use the ObjectMetadataMaps in order to fasten the process

Fixes https://github.com/twentyhq/core-team-issues/issues/1179
2025-08-29 15:04:08 +02:00
Charles BochetandGitHub e6c87a360d Compute Filter DisplayValue at runtime on FE (#14148)
<img width="1913" height="979" alt="image"
src="https://github.com/user-attachments/assets/33936329-47b1-487f-94fa-54c45e7843fc"
/>

<img width="1913" height="979" alt="image"
src="https://github.com/user-attachments/assets/6ea992a5-1ac6-49f6-8da1-661ca35144aa"
/>
2025-08-29 13:54:53 +02:00
Paul RastoinandGitHub b5114a5fa3 Morph relation v2 delete: retrieve related field metadata to delete (#14142)
close https://github.com/twentyhq/core-team-issues/issues/1411
2025-08-29 11:59:32 +02:00
0bdd1c4803 Various fixes on core views (#14093)
- Fix fragments
- Add id to create inputs
- Refresh core views
- Fix kanban loading
- Fix core views creation from current view

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-29 11:20:56 +02:00
GuillimandGitHub 0e6ce123c9 Morph-picker-MultiSelect-picker (#14113)
# 🚀 Multi-Select Morph Relations / One to Many

Adds **multi-select picker support** for morph relations on the **One To
Many** side, allowing users to select multiple related records from
different object types.

### 🔑 Main Changes (TL;DR)
- **New Component**: `MorphRelationOneToManyFieldInput` for
multi-selection
- **Enhanced Hooks**: `useAttachMorphRelatedRecordFromRecord` &
`useDetachMorphRelatedRecordFromRecord`
- **Better UX**: Optimistic updates, improved search, loading states
- **24 files changed**: Mostly additions (1,277 lines added, 56 removed)


**Summary**: This adds multi-select capability to morph relations with
proper state management and optimistic updates. The changes are mostly
additive and follow existing patterns.


**TODO** :
- optimistic rendering not working currently
- single select picker (many to one)
2025-08-29 10:04:51 +02:00
nitinandGitHub ab9cabce04 [Dashboards] Graph bar chart component (#14052)
closes https://github.com/twentyhq/core-team-issues/issues/1372
2025-08-29 09:59:27 +02:00
martmullandGitHub 71d97c5398 14064 extensibility add coretriggereventlistener table (#14138)
This Pr continues the extensibility journey
- adds a `core.databaseEventTrigger` table
- add a oneToMany relation between `core.serverlessFunction` and
`core.databaseEventTrigger`
- add a job `CallDatabaseEventTriggerJobsJob` triggered by
`EntityEventsToDbListener` triggering `serverlessFunction` based on the
`core.databaseEventTrigger.settings.eventName`
- add a new `trigger-queue` to carry this job
- renamed `DatabaseEventTriggerListener` into
`WorkflowDatabaseEventTriggerListener`
2025-08-29 08:11:35 +02:00
Paul RastoinandGitHub b364acf5bb Morph relation validation v2 (#14141)
## Introduction
Binding morph relation validation to relation validation code flow
Please note that ALL create field will go through basic atomic
validation, which involve name availability and so on

close https://github.com/twentyhq/core-team-issues/issues/1407
2025-08-28 16:05:58 +00:00
WeikoandGitHub af6fc1e9ef Add universal identifier to view tables (#14139)
## Context
Introducing a new SyncableEntity abstraction that can be extended by
Entities that we want to "sync" via their universal identifier (the
class will add this uuid to the entity). Starting with views, will
refactor existing syncable entities such as objects/fields later
2025-08-28 17:33:39 +02:00
Paul RastoinandGitHub 7c481abf0c Handle input transpilation morph relation v2 (#14124)
# Introduction
From `morphRelationCreationPayload` to `flatFieldMetadatas`

close https://github.com/twentyhq/core-team-issues/issues/1406

## Unit testing
I'm not a fan of covering things this way, where we could have some
strong integration testing tests in the first place
But I wanted to freeze the optimistic path computation, also covered the
exception because it was cheap, doesn't mean I won't cover them through
integration tests later anw
2025-08-28 17:22:03 +02:00
Félix MalfaitandGitHub e264d7f32b fix: Enable Lingui recommended rules and fix all translation violations (#14133)
- Enable lingui/no-single-variables-to-translate and all other
recommended Lingui rules
- Fix single variable translation patterns (t`${variable}` → variable)
- Fix expression-in-message violations by extracting variables
- Fix t-call-in-function violations by moving translations inside
functions
- Update ESLint configs to use linguiPlugin.configs['flat/recommended']
- Clean up unused imports and improve translation patterns
2025-08-28 15:12:38 +02:00
neo773andGitHub 6eb9a4e024 Smtp username (#14134)
Tested with vendor resend.com

/closes #14120
2025-08-28 14:49:39 +02:00
martmullandGitHub 9b41a3be54 Add cron trigger table (#14110)
This Pr begins the extensibility journey
- adds a `core.cronTrigger` table
- add a oneToMany relation between core.serverlessFunction and
`core.cronTrigger` (one serverlessFunction can be triggered by multiple
cronTriggers)
- add a job to trigger a serverless function
- adds a cron to trigger serverlessFunction (via the trigger job) based
on the core.cronTrigger.setting.pattern
- adds a command to register the cron
- add the command in `cron-register-all.command.ts`
2025-08-28 14:47:48 +02:00
Lucas BordeauandGitHub 85e6fe8849 Fix storybook build cache and logs (#14130) 2025-08-28 14:46:43 +02:00
WeikoandGitHub dec2239ae7 Remove typeorm service (#14116)
## Context
To simplify the way we inject our default datasource, I've recently
removed the token injection that was confusion since we only had once
configured on the module level. Now I'm removing TypeORM service which
allows us to instantiate a new Datasource with the same parameters as
the default one, it was redundant and confusing.
2025-08-28 13:21:26 +02:00
Félix MalfaitandGitHub f1706670f5 Modify translation compilation condition in Github Workflow (#14128)
Translations weren't pulled because --strict does not fail since we've
set english as a fallback locale (since english is set as a fallback it
considers translations have been found and therefore the command does
not fail as expected).

Temporary hotfix but we should do something smarter in the future

@ehconitin fyi
2025-08-28 13:10:12 +02:00
c15f5c07f8 i18n - translations (#14126)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-28 12:35:22 +02:00
Paul RastoinandGitHub 59d90bedaa Integration testing v2 enum field types fail and success path (#14010)
# Introduction
Migrating and improving performances of field enum integrations tests
success and failing tests cases to be using the new v2 api

## Discovered issue
When deleting an object in v1 it will leave related enums until the
object is re-created
Something not done anymore within the create in v2 but in the delete
operation
We should implem an upgrade command to remove such relicas

## Bugs
- Update/create default value multi select runner wrong sql query -> FIX
- Update default value multi select regression, we should allow option
without an id to be inserted -> FIX
- default value compare dynamic json stringify convertion or not in
compare tools for object and fields
2025-08-28 10:23:04 +00:00
WeikoandGitHub 533d7fe49a Deprecate legacy core datasource token (#14096) 2025-08-27 20:09:54 +02:00
c6aa419c18 i18n - translations (#14114)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-27 18:36:40 +02:00
Raphaël BosiandGitHub c5f7dc9e6e Create Dashboard Workspace Entity (#14112)
Closes https://github.com/twentyhq/core-team-issues/issues/1392

- Added a workspace gate on the entity for the feature flag
`IS_PAGE_LAYOUT_ENABLED`
2025-08-27 18:20:06 +02:00
Thomas TrompetteandGitHub e449e69f4c Add counter to filter (#14108)
See figma
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=70822-35001&m=dev

<img width="75" height="61" alt="Capture d’écran 2025-08-27 à 16 57
46"
src="https://github.com/user-attachments/assets/e41290c8-3ec5-4d64-a5d2-d52bd14ccd57"
/>
<img width="75" height="61" alt="Capture d’écran 2025-08-27 à 16 57
58"
src="https://github.com/user-attachments/assets/710d5735-c256-47fc-ad2f-93e4f72b8002"
/>
<img width="121" height="89" alt="Capture d’écran 2025-08-27 à 16 16
33"
src="https://github.com/user-attachments/assets/0c8216b2-f251-4f0e-ad9f-f3a25229df40"
/>



https://github.com/user-attachments/assets/43156c0c-91b8-4386-a971-e37577e3c199
2025-08-27 15:25:18 +00:00
Raphaël BosiandGitHub 58db0c9b0a Create PageLayoutWidgetEntity (#14106)
Closes https://github.com/twentyhq/core-team-issues/issues/1391
2025-08-27 16:12:54 +02:00
Raphaël BosiandGitHub 262ee457ef Create PageLayoutTab entity (#14104)
Closes https://github.com/twentyhq/core-team-issues/issues/1390
2025-08-27 15:20:24 +02:00
Thomas TrompetteandGitHub a1fe1d7f47 Display relation field id reaching max depth (#14101)
Search record action do not fetch relations. We could add it to but the
logic used, based on gql filtering will be refactored soon. Issue it
that the output schema of the step is displaying relation content as if
there were available.

This PR:
- remove the relation content from search record output schema
- replace it by the relation field id so the user can still use it
- makes UUID selectable in object record picker field

Before 


https://github.com/user-attachments/assets/1bdb4c24-ef32-4a15-9da9-149f270abb01

After


https://github.com/user-attachments/assets/d6e97160-c5a3-4989-a603-0c7ce8128b31
2025-08-27 14:36:05 +02:00
Abdul RahmanGitHubFélix Malfaitgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
9098df7ddf Add preconfigured Workflow creation agent (#13855)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-08-27 14:20:38 +02:00
Raphaël BosiandGitHub 28de78bfc0 Create PageLayoutEntity (#14099)
Closes https://github.com/twentyhq/core-team-issues/issues/1389
2025-08-27 10:34:02 +00:00
martmullandGitHub 850a0fdea2 Add command to update workflow version steps positions (#14098)
Reopening https://github.com/twentyhq/twenty/pull/13721 after some
updates
2025-08-27 12:01:33 +02:00
martmullandGitHub a6fb4dd589 Fix handle color on workflow run steps (#14091)
## Before

<img width="2878" height="1316" alt="image"
src="https://github.com/user-attachments/assets/0e1238b7-b602-4283-ae55-dccd51aa4d90"
/>


## After
<img width="1322" height="495" alt="image"
src="https://github.com/user-attachments/assets/d1f3c912-ebf4-494f-b606-21d11b3e0058"
/>
2025-08-27 10:22:13 +02:00
Raphaël BosiandGitHub 56895d785a Create IS_PAGE_LAYOUT_ENABLED feature flag (#14094)
Create IS_PAGE_LAYOUT_ENABLED feature flag
2025-08-26 19:29:58 +02:00
WeikoandGitHub f06786d603 Add missing FK on view tables (#14084)
## Context
View tables were missing some FK, we are also introducing delete cascade
on those tables when needed to leverage pg cascade deletion instead of
having to implement it.
Also renaming those classes with Entity suffix to follow repo
guidelines.
2025-08-26 18:59:20 +02:00
6d4cae973f i18n - translations (#14089)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-26 16:46:58 +02:00
5c2c063ee4 i18n - translations (#14088)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-26 16:39:17 +02:00
WeikoandGitHub c09487b943 Remove view FK on workspace favorite entity (#14086)
## Context
We are about to move view from workspace schema to core schema however
favorite table is still referencing the old table which means we can't
insert new records without breaking the constraint. This PR removes it
(and we don't have any plan to add a new one between core /
workspaceSchema, in fact, we might move the favorite table to core
schema as well in the future)
2025-08-26 16:39:00 +02:00
martmullandGitHub 0f347e2f42 Fix connection design (#14070)
- refactor edges related files into sub-module
- remove top handle from workflow, workflowVersion and workflowRun
- add a custom design for connection (edge being created)
- connect when hovering a connectable node
- fix marker z-index
- refactor Handles

## Before


https://github.com/user-attachments/assets/013dec36-5cc7-4561-938c-404511118578

<img width="934" height="409" alt="image"
src="https://github.com/user-attachments/assets/2b43c6cb-0bf3-4110-b1cc-b2e50c15c9a8"
/>



## After


https://github.com/user-attachments/assets/a5b32cbf-bfbd-48e6-9889-037234adf38f

<img width="1433" height="599" alt="image"
src="https://github.com/user-attachments/assets/02edc085-9b23-4434-b666-bf25e5c430a8"
/>
2025-08-26 16:33:39 +02:00
750dfcfc3b i18n - translations (#14087)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-26 15:39:49 +02:00
Thomas TrompetteandGitHub f4312422ce Allow to select full object and object id in filters (#14083)
Today WorkflowVariablesDropdownAllItems is used for variable picker in
all workflow steps, and for step field picker in filters.
Using that component in filters prevent us from knowing if a full record
or only the id has been selected.

This PR:
- creates a new component WorkflowDropdownStepOutputItems, mostly
copying the logic of WorkflowVariablesDropdownAllItems
- call it WorkflowStepFilterFieldSelect, removing the display logic from
that parent component
- store isFullRecord in filter. So we now know if we should display a
record picker or a uuid picker

Before - selecting id makes picker behaves like when we select an object


https://github.com/user-attachments/assets/bde34dc5-8011-4983-8d0f-d8cb0cb3c045

After - selecting object and id are two different things


https://github.com/user-attachments/assets/49289990-3e6d-4ad7-abc1-e3ade2a821bb
2025-08-26 15:31:15 +02:00
1640aea44a i18n - translations (#14082)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-26 13:31:42 +02:00
nitinandGitHub 50448c9b16 [Dashboards] Graph pie chart component + refactor (#14045)
closes https://github.com/twentyhq/core-team-issues/issues/1373
closes https://github.com/twentyhq/core-team-issues/issues/1368

figma
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=72808-199932&t=c7GEJKFZKI0JhRv0-0

TODO: 
- ~~refactor to have a color registry~~
- ~~refactor legend and tooltips into a separate component for reuse
across the graphs~~
- also refactor the border in between to be a common logic between pie
and gauge graphs - ***open question*** -
How should we code this border in between (renderValueEndLine), which is
a layer - it's a function that returns JSX
I could not figure out if it should be a util/component/hook? None of
them fit into the category -- hence kept them inline in both gauge and
pie charts for simplicity
2025-08-26 13:23:15 +02:00
Lucas BordeauandGitHub 8cb4058d2d Refactor table columns states and utils (#14048)
This PR refactors table columns state, hooks and utils, it removes them
and replaces them by record fields.
2025-08-26 13:17:53 +02:00
048455bbb6 Seed core views in dev + fixes (#14071)
Seed core views in dev

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-26 13:05:20 +02:00
ab4fd6a182 i18n - translations (#14080)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-26 11:01:37 +02:00
WeikoandGitHub d433a576d7 Create related records after object creation with migration v2 (view, view filters, favorite) (#14068)
## Context
This PR introduces view actions for the migration v2. We should be able
to create, update and delete views through the migration runner
independently from object actions (this is not 100% true in this PR
though as I'm still passing the object metadata to build the view)
Note: Once favorite are moved out of the workspace schema, we will have
favorite actions as well, in the meantime I have to inject some code at
the end of the createOne method from the object metadata service
2025-08-26 10:54:03 +02:00
neo773andGitHub 0c8631c1c8 Update sent folder regex (#14069) 2025-08-25 17:47:31 +02:00
neo773andGitHub 734b0bd2d2 IMAP Refactor (#14053)
- Removed `IMAPMessageLocator` service which relied on `Message-ID`
header lookups.

We now fetch messages directly by UID, which should eliminate most of
the issues we were hitting.

This had a challenge, `messageIdsToFetch` were flattened and UIDs are
only unique within their own folder.
To preserve context without modifying the core message module, I landed
on using composite keys for IMAP message IDs.

Each UID is now prefixed with its folder name, and we parse it back when
needed to recover the folder.
This feels like a reasonable trade-off since it resolves a lot of the
failures we saw with `Message-ID` lookups.

  And Syncs are faster now since there's no double scanning.

- Added `QRESYNC` support for servers that provide it, giving us faster
incremental sync.

- Refactored code to better split concerns.  

### Compatibility Test

| Server              | Status     |
|---------------------|------------|
| Gmail               |  Tested  |
| Dovecot             |  Tested  |
| Stalwart            |  Tested  |
| Titan Email  |  Tested  |
| FastMail  |  Tested  |

<img width="804" height="418" alt="image"
src="https://github.com/user-attachments/assets/b414a484-2798-4839-b395-9dd5c153effe"
/>
2025-08-25 16:42:07 +02:00
3d1842dcb3 Morph-front-display-table (#13979)
## Add Morph Relation Field Display Support for Tables (one to many &
many to one)

**Features:**
- Display morph relation fields (one-to-many, many-to-one) in table
cells
- Multi-field record retrieval for improved performance
- Enhanced table cell rendering with morph relation support

**Components Added:**
- `MorphRelationManyToOneFieldDisplay` - Shows many-to-one morph
relations
- `MorphRelationOneToManyFieldDisplay` - Shows one-to-many morph
relations


TODO : 
handle notes and tasks case if we choose these kind of objects as
targets/source for a morph relation

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-25 16:12:49 +02:00
dff00e813c Add coreView state in FE (#14034)
Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-08-25 15:49:21 +02:00
Thomas TrompetteandGitHub 293cf0be39 Search variables - finish the search by step type (#14046)
- Add a specific search and type for find records step. Will be mainly
useful when we start fetching list of records
- Same for forms
2025-08-25 13:48:12 +00:00
martmullandGitHub 97e5f06ff9 Fix edge design on hover (#14061)
## Before



https://github.com/user-attachments/assets/d44c9c20-fcf0-4f79-8ebf-8e03202c3559

## After



https://github.com/user-attachments/assets/ac7ef2ff-585e-49c1-96f9-63d6bea8de3f
2025-08-25 15:14:05 +02:00
Antoine MoreauxandGitHub 9f16b13843 feat(ai): add integration tests for MCP controller and improve JSON-R… (#14047)
…PC validation

- Introduced full integration test suite for MCP controller, testing
`POST /mcp` with valid and invalid payloads.
- Added `@IsDefined` validation to ensure the `method` field is required
in JSON-RPC requests.
- Applied `RestApiExceptionFilter` to MCP controller for consistent
error handling.
- Enhanced validation pipe in MCP controller to whitelist and reject
non-whitelisted properties.
- Consolidated exception filters in SSOAuthController.
2025-08-25 10:30:38 +02:00
Thomas TrompetteandGitHub 6c5a265a4e Fix staled run cron (#14044)
- Dequeue workflows when enqueuedAt is Null
- Rename cron cleaner + add it to the registered crons
2025-08-22 14:55:43 +02:00
Thomas TrompetteandGitHub 4ecd275f5e Add separated types + build a search for records (#14014)
The code to search variables became too complex. This is mainly because
it tries to handle all use cases at once:
- steps returning records (MANUAL TRIGGER, CREATE RECORD...)
- steps returning record events
- primitive types (code, webhook...)
- forms

To make the code maintainable, let's make a few updates:
- clear schema output types for each steps
- group the output types that are similar and implement a search schema
function for each
- once this is implemented on frontend, let's remove the logic on
backend side. Schema should be recompute and not stored

This PR implement the refacto for steps returning records and events.
2025-08-22 10:20:07 +00:00
Antoine MoreauxGitHublhduhuxiancgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
91ce3d4e0c fix(ai): MCPCore findRecord tool (#14033)
Fix #13545

---------

Co-authored-by: lhdu <lhdu@bigquant.ai>
Co-authored-by: huxianc <47603705+huxianc@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-08-22 12:05:56 +02:00
GuillimandGitHub c89dba9a9b Curor rules imporvement (#14042)
- Adding description to make the rules effective in the project

- Adapt the auto-attach setup
2025-08-22 12:02:30 +02:00
nitinandGitHub 7bd6d27c0d fix: resolve N+1 query issue in view name resolver with DataLoaders (#14037)
## What
Fixed N+1 query issue where each view's name resolution triggered a
separate DB query to fetch objectMetadataId, even though it was already
available in the parent view object.

## How
- Added `objectMetadataLoader` to DataloaderService to batch metadata
lookups
- Updated ViewResolver to use context.loaders (following existing
pattern from other metadata
  resolvers)
  - Removed unused `getObjectMetadataByViewId` method and its tests

Now uses the already-loaded `view.objectMetadataId` directly instead of
making unnecessary
  queries.

  Much cleaner!
2025-08-22 09:45:50 +02:00
96fd12ec7c i18n - translations (#14039)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-22 09:43:23 +02:00
nitinGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
9e9fa6325f [Dashboards] Graph gauge chart component (#14035)
closes https://github.com/twentyhq/core-team-issues/issues/1374
figma -
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=72808-199932&t=C0BfdTmTl69RKZvU-0

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-08-22 09:35:47 +02:00
Charles BochetandGitHub 953f1e7207 Fix CI cache for storybook (#14038)
In this PR:
- Migrate twenty-ui to ES2020 (removing undesired type errors during
build)
- Make CI cache work again between `sb-build` and `sb-test` steps

(Note: also fixing a minor bug on Notes)

Total CI time: ~8min
<img width="1088" height="531" alt="image"
src="https://github.com/user-attachments/assets/0bd0a99a-c69e-491d-91b2-9ddf6622464a"
/>

Both node_modules and sb-build caches are being hit now
<img width="1154" height="722" alt="image"
src="https://github.com/user-attachments/assets/a5addcee-51d2-4f51-9ff6-d02cd25da49a"
/>
2025-08-22 09:34:35 +02:00
GuillimandGitHub 156a29da8f adding upgrade version command (#14032) 2025-08-21 17:22:57 +02:00
GuillimandGitHub 595dc5cc81 non edit (#14031)
do not edit relation if ssiter relation is a morph
2025-08-21 16:46:37 +02:00
GuillimandGitHub 35df56e7d8 morph fix for release 1.4 (#14029)
DataLoader Specific update du to Morph relations that have many rows

Fixes https://github.com/twentyhq/twenty/issues/14018
2025-08-21 14:43:14 +00:00
WeikoandGitHub 707043c3ba Rollout field permissions (#14024)
Rolling out field permissions feature
2025-08-21 16:17:28 +02:00
Charles BochetandGitHub fa78762cbb Fix title cell (#14025) 2025-08-21 15:26:46 +02:00
Thomas TrompetteandGitHub 7225078743 Filters: Fix readonly on record picker + select label (#14026)
As a filter V1, we do not distinguish between selecting Id and full
record. We always should display the record

Before - Id and readonly not working

<img width="492" height="256" alt="Capture d’écran 2025-08-21 à 15 10
56"
src="https://github.com/user-attachments/assets/5152b43f-bbda-436b-97fe-d8e391b47832"
/>

After - Object name and readonly working

<img width="492" height="256" alt="Capture d’écran 2025-08-21 à 15 10
15"
src="https://github.com/user-attachments/assets/e35eeb1e-135c-4213-8b59-55a5d10da82b"
/>
2025-08-21 13:26:26 +00:00
WeikoandGitHub 1c5f8c3db5 Rollout 2FA (#14023)
Rolling out the 2FA feature for all users.
2025-08-21 14:31:24 +02:00
Thomas TrompetteandGitHub b9b5f9a347 Remove workflow filters from lab (#14017)
As title
2025-08-21 14:30:36 +02:00
Charles BochetandGitHub f7709955f6 Fix hover on inline cell (#14022)
As per title, there was some left overs
2025-08-21 12:41:12 +02:00
7ae26f04dd fix: prevent selection clicking outside the table (#14007)
Fixed issue #13869

Added flag to prevent selection of content inside ScrollWrapper based on
value of preventTextSelection flag this will prevent selection of its
all child. For to select title and description I added custom css for
that to allow selection for title and description.

Demo : 


https://github.com/user-attachments/assets/d10a7e5f-6498-4f8d-9aa2-26f48559ce23

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-08-21 09:40:42 +00:00
f0a59829a5 i18n - translations (#14015)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-21 11:34:37 +02:00
f89a01342b fix ui as per figma file (#14008)
Fix issue: #13742
Step number look better then without number so did't removed that 
Added description in H2Title component 
Not added new description shown in figma because it is to large and
H2Title truncate after 2 lines
We can add this figma content only if we do not use H2Title component 

<img width="719" height="553" alt="image"
src="https://github.com/user-attachments/assets/1aae680f-de4e-424b-baf7-c0d402581d28"
/>

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-08-21 09:20:32 +00:00
Antoine MoreauxandGitHub 809fe5699f feat(ai): enhance metadata handling and add support for tools, prompt… (#14002)
…s, and resources

- Removed unused `ObjectMetadataStandardIdToIdMap`.
- Updated Vite config with additional allowed hosts.
- Improved MCP service to handle `ping` method and lists for tools,
prompts, and resources.
- Refactored utility function `isFieldMetadataEntityOfType` for improved
type handling.
- Expanded MCP metadata service to include tools, prompts, and resources
support.
2025-08-21 08:45:46 +00:00
758fb9ecad i18n - translations (#14004)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-20 19:38:16 +02:00
Paul RastoinandGitHub e99c67d6b5 Fail slow + structured validator error response scoped by object and fields (#13980)
# Introduction
Example of returned response: ( snapshot copy don't mind jest expect any
values )
```json
{
  "extensions": {
    "code": "BAD_USER_INPUT",
    "errors": {
      "fieldMetadata": [
        {
          "errors": [
            {
              "code": "INVALID_FIELD_INPUT",
              "message": "Name is too long",
              "userFriendlyMessage": "Name is too long",
              "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
            },
          ],
          "id": Any<String>,
          "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "objectMetadataId": Any<String>,
          "operation": "create_field",
        },
        {
          "errors": [
            {
              "code": "INVALID_FIELD_INPUT",
              "message": "Name is too long",
              "userFriendlyMessage": "Name is too long",
              "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
            },
          ],
          "id": Any<String>,
          "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "objectMetadataId": Any<String>,
          "operation": "create_field",
        },
        {
          "errors": [
            {
              "code": "INVALID_FIELD_INPUT",
              "message": "Name is too long",
              "userFriendlyMessage": "Name is too long",
              "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
            },
          ],
          "id": Any<String>,
          "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "objectMetadataId": Any<String>,
          "operation": "create_field",
        },
        {
          "errors": [
            {
              "code": "INVALID_FIELD_INPUT",
              "message": "Name is too long",
              "userFriendlyMessage": "Name is too long",
              "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
            },
          ],
          "id": Any<String>,
          "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "objectMetadataId": Any<String>,
          "operation": "create_field",
        },
        {
          "errors": [
            {
              "code": "INVALID_FIELD_INPUT",
              "message": "Name is too long",
              "userFriendlyMessage": "Name is too long",
              "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
            },
          ],
          "id": Any<String>,
          "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "objectMetadataId": Any<String>,
          "operation": "create_field",
        },
      ],
      "objectMetadata": [
        {
          "errors": [
            {
              "code": "INVALID_OBJECT_INPUT",
              "message": "Name is too long",
              "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
            },
          ],
          "fields": [],
          "id": Any<String>,
          "namePlural": "listingas",
          "nameSingular": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "operation": "create_object",
        },
      ],
    },
    "message": "Validation failed for 1 object(s) and 5 field(s)",
    "summary": {
      "invalidFields": 5,
      "invalidObjects": 1,
      "totalErrors": 6,
    },
    "userFriendlyMessage": "Validation failed for 1 object(s) and 5 field(s)",
  },
  "message": "Multiple validation errors occurred while creating object",
  "name": "GraphQLError",
}
```

## Note
We should put in place integrations tests on REST API too, in order to
ensure we receive the same response error
2025-08-20 17:33:15 +00:00
dematrixandGitHub 4752970f79 Removed Redundant Filter Option in Filter Menu (#14003)
Removed Redundant Filter Option in Filter Menu

File Changed : WorkflowDiagramFilterEdgeEditable.tsx

Issue : #13908
2025-08-20 19:15:21 +02:00
30c42345f0 Core views frontend (#13932)
Parallel code path to read and write core views when
IS_CORE_VIEW_ENABLED.

Migrated view key to an enum.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-08-20 19:04:58 +02:00
WeikoandGitHub deec9c96da Refactor schema migration runner service discovery (#13988)
## Context
This refactoring improves scalability in the workspace migration runner
in terms of actions. Instead of relying on a switch case and multiple
changes and services + duplicate things between metadata and workspace
schema, we now have a unique module for all kind of actions and a
registry pattern to register them and run them dynamically.

Example on how to add a new "create_role" action with the future design:
```typescript
// packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/role/services/create-role-action-handler.service.ts
export class CreateRoleActionHandlerService extends WorkspaceMigrationRunnerActionHandler(
  'create_role',
) {
  constructor(
    private readonly workspaceSchemaManagerService: WorkspaceSchemaManagerService,
    private readonly roleRepository: Repository<Role>,
  ) {}

  async executeForMetadata(
    context: WorkspaceMigrationActionRunnerArgs<CreateRoleAction>,
  ): Promise<void> {
      this.roleRepository.save({...}); // technically could use the queryRunner from context param directly instead of injecting the repository
  }

  async executeForWorkspaceSchema(
    context: WorkspaceMigrationActionRunnerArgs<CreateRoleAction>,
  ): Promise<void> {
      // this.workspaceSchemaManagerService.tableManager... -> Nothing to do in the workspace schema in the role case
  }
}
```
```typescript
// packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts
@Module({
  imports: [WorkspaceSchemaManagerModule, +TypeOrmModule.forFeature([Role]),
  providers: [
     ...
     +RoleCreateActionService
  ],
})
export class WorkspaceSchemaMigrationRunnerActionHandlersModule {}
```
```typescript
export type WorkspaceMigrationAction=
  | WorkspaceMigrationObjectAction
  ...
  +| WorkspaceMigrationRoleAction;

export type CreateRoleAction = {
   type = 'create_role',
   role: RoleEntity
};

export type WorkspaceMigrationRoleAction = CreateRoleAction;
```
2025-08-20 18:30:40 +02:00
f994f9d512 i18n - translations (#14000)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-20 18:18:01 +02:00
ff3f1d945c [feature]:Improved Options Menu for Default View (#13427)
**Feature** - Improved Options Menu for Default View

**Closes** - #13306

**Description** 

This PR fixes the feature request of Better Options in the Default View.
Added the option of Create a Custom View in the Options, this helps user
create custom views.


**Working Demo** 


https://github.com/user-attachments/assets/32a3f264-c4a0-42aa-9257-56a407ea3c6e

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-08-20 18:09:22 +02:00
Kailash RajputandGitHub f72c3d73bf fix: fix position of checkbox and icon (#13999)
Minor UI Fix 

Checkbox and icon are not center horizontally which look little odd so
make them horizonatally center

Before 
<img width="396" height="57" alt="Screenshot 2025-08-20 at 8 48 23 PM"
src="https://github.com/user-attachments/assets/1505b2e6-6b39-498b-a1be-93d11ca89494"
/>

After 
<img width="392" height="56" alt="image"
src="https://github.com/user-attachments/assets/ffa68625-8014-4e58-9211-3e9b822dfa35"
/>
2025-08-20 18:07:39 +02:00
42a760a94d i18n - translations (#13998)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-20 17:30:49 +02:00
bbf26febb6 Perform renaming fixes and implement full access card (#13912)
Closes #13861

`All Objects` has been renamed to `Objects` and `Name` has been replaced
with `All Objects`. There was no specification of whether the `Data full
access` card had to be implemented or not. Do let me know if that needs
to be removed or something needs to be changed in its configuration.

Attaching a loom recording of the changes:
[Loom
Recording](https://www.loom.com/share/42b54e9386b14619bc1118e95eb62293?sid=10ac8e8a-475b-4870-bd36-64742cd8c3c5)

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-08-20 15:17:16 +00:00
4b66e8021a Fix filters + add behaviour for select (#13997)
On field selection, we need to retrieve the fieldMetadata to set the
filter type. Current code was using the current step filter
fieldMetdataId instead of the new one.

Also adding a special behaviour for Select filter: it behaves as
arrays/multiselect but the opearands are not the same.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-20 17:14:31 +02:00
f9abea2387 Fix table aligment issue (#13896)
Closes #13862 

The `padding-right` for `StyledCheckboxCell` was previously set to
`16px`, causing it to be pushed in. It has now been reduced to `8px`.
The read column in the table appeared as the third column regardless of
whether update was restricted or not. Now, the read column appears as
the last column if update is restricted, otherwise, read appears before
update column.

Attaching a recording for verification:
[Loom
Recording](https://www.loom.com/share/ebd07db6c4d04900aa18f3a1ba71e770?sid=75b33043-dc80-4e2d-82ae-f183efa6faa2)

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-08-20 14:37:24 +00:00
da3479a4f4 Multi drag on tables + Refactor (#13570)
https://github.com/user-attachments/assets/32d20ca0-fa50-427c-92e8-638884d86de3


- code needs refactoring
- ~~missing stack behaviour (I dont think its easy to add something
similar here, but will give it a try) - I suspect it will look crowded~~
- ~~the notification counter - boards have it on top right, but on
tables we cant do that since the rows could be longer than the scrolling
container , therefore I added it on top left corner~~
- ~~needs to test with large set of data for both boards and tables
(pagination)~~

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-08-20 15:16:07 +02:00
Thomas MolandGitHub 85dfcfbb18 Add community Railway template in self-hosted cloud provider docs (#13986) 2025-08-20 14:33:57 +02:00
a9156666e5 fix: set content-type header for isMethodWithBody (#13839)
Fixes Workflow HTTP Request not setting `content-type` header for JSON
body it was defaulting to `application/x-www-form-urlencoded` causing
parsing issues

<img width="1496" height="847" alt="image"
src="https://github.com/user-attachments/assets/c4bd6ac3-0f4a-47eb-b108-fae95338c019"
/>

/closes #13781

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-08-20 14:20:13 +02:00
Balaji KrishnamurthyandGitHub fc39f35ced Animate between IconX and IconReload (#13949)
Closes #13866 

An animation of 150ms has been introduced to all icons that are rendered
inside `OverridableCheckbox`. Attaching a recording of the same.
[Loom
Recording](https://www.loom.com/share/65293c13171a4bf8934c577eecbca9a0)
2025-08-20 12:09:06 +02:00
3a13d240b4 i18n - translations (#13996)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-20 12:08:11 +02:00
Antoine MoreauxandGitHub dcdf675000 fix(ai): improve mcp metadata logic (#13991)
Fix #13801
2025-08-20 12:06:13 +02:00
nitinandGitHub 69649e97d4 get rid of singleton usage in view resolver (#13990)
addressing -
https://github.com/twentyhq/twenty/pull/13895#pullrequestreview-3133235956

will be addressing performance issue in another follow-up -- need to get
the strategy straight
2025-08-20 12:04:41 +02:00
Lucas BordeauandGitHub 00478152e0 Refactor field definition and column definition manipulation with record field (#13992)
This PR introduces the usage of record fields in the manipulation of
table columns and board fields.

Since all of the actual system relies on states like tableColumns,
recordIndexFieldDefinitions and the likes, it was required to implement
temporary utils that modifies those states in parallel of the new
generic currentRecordFields, to keep a working product.

With this PR though, currentRecordFields becomes the single source of
truth that gets saved to DB, and the remaining work is just to make the
switch with this new state on all components that are plugged to
tableColumns and the like.

This will be done in another PR.
2025-08-20 12:03:12 +02:00
3f6866da20 i18n - translations (#13993)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-20 11:46:46 +02:00
521ef5ea4c fix: workflow node classification (#13945)
closes #13391 
As the solution said to classify workflow nodes based on colors I have
updated them with the following colors and new categories to better
classify and identify different node types as told:

  - Trigger Colors: Data (palette blue), Other (palette purple)
- Action Colors: Data (text/tertiary), AI (palette pink), Flow (tag
green), Human Input (palette orange)
 
<img width="451" height="690" alt="image"
src="https://github.com/user-attachments/assets/8c000f22-8f25-4b1d-ac6f-f2639b1eff94"
/>

<img width="451" height="690" alt="image"
src="https://github.com/user-attachments/assets/15a11a98-3fec-4374-a5f7-d7caf2ae5334"
/>

<img width="480" height="690" alt="image"
src="https://github.com/user-attachments/assets/6382f538-be6d-4595-b967-e7911f7ad61f"
/>

<img width="899" height="761" alt="image"
src="https://github.com/user-attachments/assets/98c97cd4-54cd-4bee-91b5-dd7cd3b03a5e"
/>

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-08-20 11:31:03 +02:00
nitinandGitHub ae160e8b15 [Dashboards] Graph number chart component (#13984)
closes https://github.com/twentyhq/core-team-issues/issues/1375

figma -
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=72808-199932&t=3pZFwiYnRynSMyJP-0
2025-08-20 08:44:44 +00:00
neo773andGitHub 44916afcdd fix extract-message-util preserve line break for multi line HTML text (#13983)
Upon more testing with titan email I found emails with multi line text
did not preserve line break in HTML, this fixes it.
2025-08-20 07:49:05 +02:00
WeikoandGitHub 2fc29d41a8 Fix enum deletion during migration v2 (#13977)
## Context
- When deleting an object, we were not properly deleting all the enums,
in fact some enums were inside composite fields and should have been
handled as well. This was already implemented that way for object update
and creation but not deletion.
- Fixing an issue where creating a field with an empty string as a
default value was skipped and causing an issue with non-nullable columns
2025-08-19 19:47:27 +02:00
1b94621c05 fix: sort search results by TSRank (#13875)
Before:


https://github.com/user-attachments/assets/85ecf0c9-fa51-4aff-ac4a-7743a845542b




After:





https://github.com/user-attachments/assets/60f81eaf-cd7c-4da5-9f44-cbdd223c8f90





/closes #11804

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-08-19 19:37:25 +02:00
nitinandGitHub 025eaff9ec Add translations on core views (#13895)
closes https://github.com/twentyhq/twenty/issues/11999
2025-08-19 19:35:53 +02:00
neo773andGitHub c582666aeb IMAP FIxes (#13973)
- Added `ImapFindSentMailboxService` to replace utility function it
fixes an edge case where special flag `Sent` folder may have zero
messages, we fall back to regex based approach to find other candidates
- Fixed edge case where some servers may not return text content for
body it parses the HTML in that case
- Some other enhancements with capability based detection

Tested with Stalwart server and Titan email

/closes #13884
2025-08-19 19:22:13 +02:00
GuillimandGitHub d63ede5aca morphfix (#13978)
quick fix
2025-08-19 18:16:41 +02:00
3ef94f6e8c Refactor read only object and fields (#13936)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-19 18:10:35 +02:00
bb7cd1baa1 i18n - translations (#13976)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-19 16:48:04 +02:00
90c237a185 Morph-front-settings (#13872)
# Implement Morph Frontend Settings

Possiblity to create a morh relation from the Settings !

## Overview
Morph object system with new frontend settings UI for configuring morph
relations.

## What Changed
- **New Components**: `SettingsDataModelFieldMorphRelationForm`,
`SettingsMorphRelationMultiSelect`
- **Form System**: React Hook Form + Zod validation for morph relation
configuration
- **Preview System**: Live preview of field configurations with
validation
- **State Management**: Enhanced component state handling for complex
form interactions

## Technical Details
- **Architecture**: Restructured field input/display components for
better maintainability
- **Types**: Added comprehensive TypeScript types for morph relations
(`isFieldMorphRelation`, etc.)
- **Validation**: Dynamic validation rules based on field types and
relation patterns
- **Performance**: Optimized rendering with proper state management

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-19 16:37:26 +02:00
Paul RastoinandGitHub 9eaede6e1e Fix default relation standard field deletion (#13975)
Authorize relation standard field deletion if targetObjectMetadata is
not present in existingFlatObjectMetadataMaps
2025-08-19 16:12:04 +02:00
nitinandGitHub 9d90a2e67f add view related schema definitions to computeMetadataSchemaComponents (#13971)
### The Issue

Every PR is currently failing the REST API breaking changes check with
errors like:
```
  Could not find /components/schemas/ViewForResponse
  Could not find /components/schemas/View
  Could not find /components/schemas/ViewForUpdate
  ...
  ```

  This is happening because the View REST endpoints were added to main `(/rest/metadata/views, /rest/metadata/viewFields, etc.)` but the corresponding OpenAPI schema definitions were missing from components.utils.ts.

 ### The Fix

  Added the missing schema definitions for all View-related entities:
  - view, viewField, viewFilter, viewSort, viewGroup, viewFilterGroup
  - Each entity includes 3 schema variants: base, ForUpdate, and ForResponse

  This ensures the OpenAPI spec properly documents what's already exposed.

 ### Note about CI

  This PR will still show the error in CI since it's comparing against the current main branch. Once merged, this should
  resolve the issue for future PRs.

###  Open Question

  Should the View REST endpoints be gated behind the IS_CORE_VIEW_ENABLED feature flag? Currently they're always exposed
  while the GraphQL resolvers do check this flag. Happy to add that in a follow-up if needed.
2025-08-19 15:01:45 +02:00
e60e2bd342 fix: remove unnecessary spacing in search node's conditional operator field (#13946)
fix for issue #13905
<img width="177" height="138" alt="image"
src="https://github.com/user-attachments/assets/4bb44615-8c32-441a-8fdf-4429dc4dcadc"
/>

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-08-19 14:59:23 +02:00
Paul RastoinandGitHub 86170c705e Standard relation field for custom objects (#13968)
## Introduction
Introducing default standard relation field for custom objects
2025-08-19 13:53:46 +02:00
a6145f5ea7 fix(design-system): fix menu item selection & focus state (#13807) (#13948)
Closes #13807

Demo Video: 


https://github.com/user-attachments/assets/27c94028-fe1b-4a65-800d-56eaad9599d6

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-08-19 11:54:01 +02:00
Charles BochetandGitHub 989a01e89d Fix website navigation (#13972)
<img width="1920" height="1001" alt="image"
src="https://github.com/user-attachments/assets/c57392a1-7db8-4d44-9b53-cdfaf7f5b891"
/>

<img width="1920" height="1001" alt="image"
src="https://github.com/user-attachments/assets/ecc20c7f-9ffc-4459-a504-53dbdaeb4dcf"
/>
2025-08-19 11:21:17 +02:00
ahmedobaid23andGitHub 76115309fa fix: scroll to selected element without animation when dropdown opens (#13969)
Fixes #13957 

### Changes made

- updated `scrollIntoView` options to `behavior: auto` and `block:
start` in the `SelectableListItem.tsx` component.

### New behaviour


https://github.com/user-attachments/assets/7e71e132-f6e3-4451-8ee0-fa59ae9edd67
2025-08-19 10:21:52 +02:00
Abhinav TalmaleandGitHub b5394f6ba6 minor changes - fixed text color (#13970)
closes #13902
2025-08-19 10:15:39 +02:00
WeikoandGitHub aa51ecb9d2 Fix relations creation with metadata v2 (#13967) 2025-08-18 21:48:39 +02:00
Thomas TrompetteandGitHub da560afb97 Put back transparent background for code editor (#13966)
It was black since this PR
https://github.com/twentyhq/twenty/commit/464a480043f3d6d1c4a95ecd39489f83e0611e60

<img width="500" height="655" alt="Capture d’écran 2025-08-18 à 18 36
47"
src="https://github.com/user-attachments/assets/dfb5cf01-ae0c-4048-8c3e-74022775f5b2"
/>
2025-08-18 18:52:02 +02:00
Paul RastoinandGitHub 9838dc611b Fix build field order delete object refactor (#13965)
# Introduction
- Decided to remove delete_field resulting from delete_object as ON
CASCADE will handle it
- Still ordering delete_field in first place in order to handle
relationTargetFieldMetadata deletion on passed delete_object that
contains relation field
2025-08-18 18:38:43 +02:00
Paul RastoinandGitHub 6c23c9c46b fix(server): field metadata creation service v2 (#13963) 2025-08-18 17:50:33 +02:00
3e1ca5fdc5 i18n - translations (#13964)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-18 17:47:49 +02:00
Baptiste DevessierandGitHub cded145609 Implement new workflow node design (#13929)
## Demo workflows + workflow runs


https://github.com/user-attachments/assets/f2ee9451-37c3-4fce-803e-7696093456c6

## Demo workflow versions


https://github.com/user-attachments/assets/0f40c670-3fb3-4c73-a842-549b31ae26df

## With Branches disabled


https://github.com/user-attachments/assets/a9a39515-dd18-4310-b96e-a42dbebb17d9
2025-08-18 15:40:34 +00:00
Thomas TrompetteandGitHub abe6b7828b Fix run input tab for filters (#13961)
Previous step id was still calculated the old way for step following
triggers: if first step in the array, means it follows the trigger.
It was not working for steps inserted between trigger and first step.
Removing that code for good.

Before
<img width="500" height="655" alt="Capture d’écran 2025-08-18 à 16 34
50"
src="https://github.com/user-attachments/assets/31365bfe-8c7d-45b5-8141-ac3d4e31127f"
/>

After
<img width="500" height="655" alt="Capture d’écran 2025-08-18 à 16 34
18"
src="https://github.com/user-attachments/assets/b9b42c58-0416-48a6-bc65-2966366a888c"
/>
2025-08-18 17:00:52 +02:00
5e905d3004 fix: Filter Selection Icon Missing #13901 (#13950)
Fixed issue #13901



https://github.com/user-attachments/assets/4aa7d0f3-88b8-474f-85e5-b2989ed8afdd

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-18 16:54:26 +02:00
WeikoandGitHub 43bb8d6043 Workspace schema migration runner v2 - Fix Enums and Create TsVector (#13955)
## Context
- Adding ts-vector generatedType/asExpression as TS_VECTOR settings
- Using those settings to setup properly tsVector searchVector column
through the new migration runner
- Fix enum creation/suppression

Note: regarding the new tsVector, we should implement a command to
update existing fields

TODO: 
- TS_VECTOR search vector column update (note: should be properly
updated whenever the object labelIdentifier is updated or a new TEXT
field is added to the object to follow the current logic)
- relation type fields and columns are not implemented yet 
- index migrations
2025-08-18 16:33:51 +02:00
Paul RastoinandGitHub 3d3191425e Workspace migration v2 builder embed field metadata validation (#13960)
# Introduction
Following https://github.com/twentyhq/twenty/pull/13934
Finalizing object migration
Also refactored existing to follow same for const loop pattern
2025-08-18 16:00:58 +02:00
Thomas TrompetteandGitHub 578a2f4e6b Handle relative date step filter (#13930)
https://github.com/user-attachments/assets/2fbb02dd-2170-4807-a1dd-faa3f374bd5a



- move relative date types to twenty-shared
- use and adapt existing relative date picker to be used in workflow
forms
- add backend logic to support relative dates in filters
2025-08-18 14:12:22 +02:00
483c1e2214 fix(filters): unify combinedFilter for queries and bulk delete (#13952)
Issue: https://github.com/twentyhq/twenty/issues/13913

Motivation/Problem:
Bulk delete and query paths were composing filters differently, causing
mismatches. In some cases this led to invalid or empty GraphQL filters
(e.g. {"and":[{}]}), breaking delete operations.

Fix:
Unify filter composition (combinedFilter) across queries and bulk
delete, ensuring consistent handling of base filters + soft-deleted
clause. Also adjusted record filter grouping logic to avoid dropping
filters when no groups exist.

Result:
Filtered queries and bulk deletes now behave consistently and reliably
without producing broken filters.

---------

Co-authored-by: root <root@DESKTOP-E2VOJGE>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-18 12:01:47 +02:00
Thomas TrompetteandGitHub 1598e5590a Fix not available workflow version id in runs (#13958)
Quick fix : make workflow version available in runs.
This would global refactor. We should not have both version and run flow
here.
I will probably stop using the same component in both at some point and
rather duplicate. Versions and Workflow will use version. Runs will use
flow.
2025-08-18 11:52:40 +02:00
025b59b5d0 i18n - translations (#13959)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-18 11:21:35 +02:00
Paul RastoinandGitHub 6629092645 Refactor builder to embed Object validation create/delete/update (#13934)
# Introduction
Moving validation directly in the builder that has the perfect
granularity to do it.
When importing we won't have to infer and dispatch on the operation
nature ( update delete create ) and validate accordingly

## Objects
Only migrated object validation for the moment even though create object
involves a validate flat field metadata creation call too

## TODO
- improve `otherFlatObjectMetadataMapsToValidate` naming too vague

## Next
- handle fields validation within fields actions build
- Unit test coverage validation issue on builder and validate
- integration test plugging with new feature flag

## Manual tested
- Update
- Delete
- Create TODO
2025-08-18 11:16:16 +02:00
18b2a68b69 i18n - translations (#13956)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-18 10:38:17 +02:00
c342ece2ee Prepare field option dropdown for RecordField usage (#13935)
This PR prepares and simplify option dropdown for using record fields.

I had a problem while trying to use currentRecordFields directly with
ordering so I stayed with the actual column definition system.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-18 10:34:12 +02:00
Arik ChakmaandGitHub 2894d6f7c2 fix: suggestion menu item font color (#13947)
# Before
<img width="241" height="246" alt="image"
src="https://github.com/user-attachments/assets/91f8ae1c-8d26-4b0a-b87b-0b26ba3676ac"
/>

# After
<img width="239" height="231" alt="image"
src="https://github.com/user-attachments/assets/e3da0dd2-c0d7-4180-83c1-a000a26189eb"
/>
2025-08-17 10:12:50 +02:00
neo773andGitHub f9eca8f116 fix: merge records settings select (#13944) 2025-08-16 16:46:08 +02:00
StephanieJoly4andGitHub 782cf5dba1 Updating user guide index (#13942)
- changing a mxd to mdx format
- updating the user guide index that was still referencing the old
structure - see attached screenshot for past structure
<img width="1405" height="864" alt="Screenshot 2025-08-16 at 10 33 14"
src="https://github.com/user-attachments/assets/cd14f233-c9c7-4426-b61b-40eb038b3a55"
/>
2025-08-16 14:10:18 +02:00
45f8c427b0 i18n - translations (#13939)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-15 11:01:04 +02:00
Félix MalfaitandGitHub d0bcf8a871 Improve REST API Docs (#13931)
Various improvements to the REST API docs as we often get questions
(misconceptions on how to use filters, how to use with LLMs, etc.)
2025-08-15 10:49:00 +02:00
0c33dcc16a i18n - translations (#13933)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-14 18:49:57 +02:00
EtienneandGitHub f6d0af5fb8 Move duplicate key error handling in ORM (#13893)
Error available in REST API
<img width="1360" height="653" alt="Screenshot 2025-08-13 at 11 48 19"
src="https://github.com/user-attachments/assets/a055859d-ce54-4ff6-9aba-fac48e03a98d"
/>

`curl http://localhost:3000/rest/people \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{
  "emails": {
    "primaryEmail": "test@test.com"
  }
}'`

closes https://github.com/twentyhq/twenty/issues/13567
2025-08-14 16:38:04 +00:00
Charles BochetandGitHub 5c61daa201 Refactor board inline-cell input (#13928)
Makes board use the Input portals for Inline Cells
2025-08-14 17:43:27 +02:00
WeikoandGitHub 1707e00ad4 Workspace schema migration runner v2 (#13899) 2025-08-14 15:58:25 +02:00
c1885233bc i18n - translations (#13925)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-14 15:03:14 +02:00
Lucas BordeauandGitHub fd2b063d84 Add RecordField abstraction (#13923)
This PR adds a new RecordField abstraction to mimick the behavior of
RecordFilter, RecordSort and other similar concepts that allow to have
something that is not related directly to views.

It is closely following the same pattern with an Effect component to
initialize it from views and CRUD hooks to modify it.

Although for this concept we save to view fields automatically for every
modification.

This PR does not implement saving to view fields, it is just a parallel
code path that is meant to be built to see if everything behaves the
same then we'll remove the old code path at the end by saving record
fields instead of the many states for columns, fields definitions, etc.
2025-08-14 15:00:07 +02:00
Charles BochetandGitHub 8c78314b52 Refactor inline-cell inputs on board (#13921)
Refactor FieldsCard (aka RecordFieldList) and RecordDetailSection so
they re-use the same components
2025-08-14 14:52:38 +02:00
9ea0662936 i18n - translations (#13924)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-14 14:22:51 +02:00
56dda7c135 [fast follows] - improve rest api documentation, fix add new button being considered in drag, fix grip color (#13709)
as per title

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-08-14 14:12:13 +02:00
Thomas TrompetteandGitHub 50c4c50169 Remove workflow context + clean action config (#13919)
- Remove create related version and runs from workflow action config
- Remove WorkflowStepContextProvider. Use states instead
2025-08-14 10:17:07 +00:00
08bf7b6dca i18n - translations (#13922)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-14 11:47:53 +02:00
Paul RastoinandGitHub ad77d2f462 ObjectMetadataServiceV2.updateOne (#13891)
# Introduction
Last service to get migrated, `updateOne` object metadata service v2
2025-08-14 09:37:52 +00:00
3c034c4ab4 i18n - translations (#13920)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-14 11:21:30 +02:00
Charles BochetandGitHub cd0f9aebc0 Refactor inline-cell inputs (#13914)
Continue the work so that inline-cell do not embed their own input which
is inefficient when we have thousands of inline-cell on the table
2025-08-14 11:06:37 +02:00
455ce191e4 feat: ability to pin a manual trigger in the navbar (#13904)
Fixes #13333 

This PR adds the ability to pin a manual trigger in the navbar. As
suggested, the following changes have been made:

**Changes Made**

- **Schema updates**
- Updated the `workflowSchema.ts` and added `isPinned` to the
`workflowManualTriggerSchema` as an optional boolean.

- **Defaults**
- Updated the `getManualTriggerDefaultSettings.ts` to add `isPinned` to
the `WorkflowManualTriggerSettings`, defaulting to false.

- **UI updates**
- Updated the `ManualTriggerAvailabilityOptions.ts` to improve the
Availability labels as suggested in the figma files.
- Created a new file `ManualTriggerIsPinnedOptions.ts` that contains the
options (label, value and icon) for the `isPinned` select component.
- Updated the `WorkflowEditTriggerManualForm.tsx` to incorporate the
added `isPinned` select component.

- **Action handling**
- Modified `useRunWorkflowRecordActions.tsx` to add `isPinned:
activeWorkflowVersion.trigger?.settings?.isPinned` to the returned
action config.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
2025-08-14 09:03:35 +00:00
Baptiste DevessierandGitHub 36fcb29e86 Implement proper arrows between nodes for workflows and workflow versions (#13909)
> [!IMPORTANT]
> We still have to implement the new arrows for **workflow runs**. I
kept the old arrows because they currently indicate the success state of
an execution. In the new version, arrows will all look the same,
regardless of the execution state of the previous node, so we'll be able
to use the same arrows everywhere.

## Workflows

You can see that arrows start from the right spot and end just above the
target node. **We will soon remove the round top handle, and the arrow
will gently touch the top of the node.**


https://github.com/user-attachments/assets/febd5f49-393f-4d97-addc-bede5cf6944a

## Workflow versions


https://github.com/user-attachments/assets/e519850f-abd9-4d75-8337-c4c44a2dbfed

Closes https://github.com/twentyhq/core-team-issues/issues/1369
2025-08-14 10:05:42 +02:00
Thomas TrompetteandGitHub 88735f6788 Stop propagating full workflow in components (#13900)
Workflow, workflow version and workflow runs should not be passed
through props or context. These are set in recoil component states and
that's where all hooks should look for these.

This PR stop propagating workflow with version through all components.
2025-08-13 16:02:13 +00:00
EtienneandGitHub 5eba2a8011 UpdateMany - Process connect queries in batch (#13907)
closes https://github.com/twentyhq/core-team-issues/issues/1357
2025-08-13 17:53:04 +02:00
Charles BochetandGitHub 6528038e9e Refactor inline-cell-input hover on field-list (#13906)
This is first step toward separating the path between display mode and
input mode for inline-cells like we have done for tableCell.

The idea is to have 1 floating or anchored field input shared between
all cells. This should be done for field-list, board and task/note row +
for hover and edit mode.

This PR is only about field-list and hover
2025-08-13 17:51:11 +02:00
Raphaël BosiandGitHub b3ae72eb9a Disable nx ui terminal (#13910)
Disable nx ui terminal:

https://nx.dev/recipes/running-tasks/terminal-ui#enabledisable-the-terminal-ui
2025-08-13 17:50:10 +02:00
GuillimandGitHub 3f66e81a9f Missing the joincolumnname parsing (#13898)
in graphql-selecvted-fields-parser, we forgot to treat the
joincolumnname case, on top of the relation itself.
2025-08-13 16:49:22 +02:00
Baptiste DevessierandGitHub 36dc6cbcb8 Allow deleting any branch via keyboard (#13897)
The heart of the fixing is making edges selectable and deletable in
`packages/twenty-front/src/modules/workflow/workflow-diagram/utils/transformFilterNodesAsEdges.ts`.

## When Branches are enabled


https://github.com/user-attachments/assets/7477c556-d593-4235-8312-e830847192ca

## When Branches are disabled


https://github.com/user-attachments/assets/445c98b7-2370-4d60-b2e8-e47b05e8d8a2
2025-08-13 15:06:42 +02:00
Baptiste DevessierandGitHub dafb43be6d Make source handle blue when node is selected and on hover (#13887)
## Branches disabled


https://github.com/user-attachments/assets/a0f597df-467e-4a45-bfc0-7c55dfbbcf47

## Branches enabled


https://github.com/user-attachments/assets/99d5a1c2-6943-407e-9928-ffabd344bebd
2025-08-13 14:03:32 +02:00
25d27e904f i18n - translations (#13892)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-13 11:48:04 +02:00
38c499468f i18n - translations (#13890)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-13 11:35:55 +02:00
Lucas BordeauandGitHub 3f0ee0139c Refactor record-field into ui sub-folder (#13888)
This PR prepares the refactor of record field definition and column
definition.

We need to separate the two concepts of FieldInput and FieldContext at
the cell level, and the new RecordField concept that will replace
FieldDefinition at the metadata and state level.

So we create a new ui sub-folder in the already existing record-field
folder, in order to separate those two concepts that are still very
close.
2025-08-13 11:31:39 +02:00
Paul RastoinandGitHub e8e81957a6 ObjectMetadataServiceV2.deleteOne (#13871)
# Introduction
- Implementing the delete one for the new object metadata service v2.
- Handling relation fields and fields in the first place to finally
remove the object
- puting back updatedAt and createdAt in flat metadatas
- duplicate criteria addition for flat object
- removing datasource id from object metadata dto
2025-08-13 09:20:17 +00:00
Baptiste DevessierandGitHub 98e1a325a8 Only allow deleting branches when branches are enabled (#13889)
## When filtering is enabled


https://github.com/user-attachments/assets/820e0a3a-265d-490d-9bd2-6d1bce9900a6

## When filtering is disabled


https://github.com/user-attachments/assets/cfc6cf9f-f66b-402a-8db9-9e8a34de6feb
2025-08-13 09:19:46 +00:00
neo773andGitHub 8570f1ce03 followup #13878 (#13886) 2025-08-13 09:57:43 +02:00
Balaji KrishnamurthyandGitHub e0508470e8 Permission table fixes (#13882)
Closes #13865 
`IconEye` has been removed as specified in the issue. There was also a
`PencilIcon` for the `Edit` section, which has been removed. The
alignment issue was caused due to the `See` label being aligned to
`center`, which has now been removed. An optional parameter
`gridColumns` has been added to `StyledObjectFieldTableRow`.

Adding a screenshot for reference:
<img width="1153" height="498" alt="image"
src="https://github.com/user-attachments/assets/12357084-f8d2-45d4-9b58-651488609c07"
/>
2025-08-13 09:37:49 +02:00
8c39f5d1e4 i18n - translations (#13885)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-13 09:34:10 +02:00
Balaji KrishnamurthyandGitHub 02cf00d457 Rename permissions and fix add rule button (#13874)
Closes #13868

- `Permissions` has been renamed to `Records`
- `Add object rule` has been shortened to `Add rule`

Attaching screenshot for reference
<img width="730" height="491" alt="image"
src="https://github.com/user-attachments/assets/09141334-07ad-4916-9f3b-c9a537f52def"
/>
2025-08-13 09:27:43 +02:00
88cc8d48de i18n - translations (#13883)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-13 08:53:07 +02:00
EtienneandGitHub 6936993557 Unique fields - fixes (#13848)
- Enable update to unique for composite field with defaultValue
different from default defaultValue on subfield not included in unique
constraint
- Enable update to unique for standard field + Disable update to
non-unique for standard index
- Fix typo

Fixes https://github.com/twentyhq/core-team-issues/issues/1360
2025-08-13 08:40:46 +02:00
Balaji KrishnamurthyandGitHub f63fe5d478 Remove X icon for fields that cannot be removed (#13876)
Closes #13867
The `IconX` now only renders when `disabled` is `false`. This means,
that the IconX only appears when the field can actually be removed.

Attaching screenshot for reference
<img width="622" height="606" alt="image"
src="https://github.com/user-attachments/assets/7b8895c3-4ed1-4de9-98dc-585ee33e2960"
/>
2025-08-12 22:49:08 +02:00
af835e23be fix: sync color scheme on loading state (#13878)
Before:


https://github.com/user-attachments/assets/a769a2f8-554a-42f7-8adb-e8b4be92a4d1


Aftter:


https://github.com/user-attachments/assets/9200967a-902f-4f8d-822d-827dda32bac2

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-08-12 22:47:58 +02:00
Baptiste DevessierandGitHub 3ffb35d7a8 Bring back edge selection & deletion (#13863)
Bring back what shouldn't have been deleted.
2025-08-12 17:21:52 +02:00
978a3b9171 i18n - translations (#13870)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-12 17:01:04 +02:00
Paul RastoinandGitHub de0468d104 ObjectMetadataServiceV2.createOne (#13849)
# Introduction

Introducing v2 object metadata service create one handler v2, not
overkilling the flatObjectMetadata validation for the moment that will
require sequential validation for the import in order to handle
relations and morph relations
2025-08-12 16:49:35 +02:00
c94f33f1b7 i18n - translations (#13859)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-12 16:06:27 +02:00
Charles BochetandGitHub ef42dace30 Fix destroy many resolver broken on custom objects (#13858)
Fixes https://github.com/twentyhq/twenty/issues/13804
2025-08-12 16:04:21 +02:00
Thomas TrompetteandGitHub cee647435c Improve workflow queue cron reliability (#13818)
Improve workflow enqueue cron : instead of relying on the cache to know
how many workflows we can enqueue, query the DB. Then set the cache and
process the not started workflows.

Also adding a second cron that will look for workflows enqueued one hour
ago or more and put these back in the not started status. This will
allow the first cron to start these again.
2025-08-12 15:54:58 +02:00
Félix MalfaitandGitHub 3c0f3fd2ae Run yarn dedupe and upgrade TS (#13853)
Upgrading TS to the latest version, and cleaning up packages with yarn
dedupe
2025-08-12 15:18:59 +02:00
GuillimandGitHub 62352901ba [Morph] frontend basics init (#13822)
Basic setup for frontend work on morph relations.

FieldMetadata definition and related adjustments
2025-08-12 12:11:18 +00:00
3c6a115ace i18n - translations (#13852)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-12 13:58:33 +02:00
nitinandGitHub 7a710aee3c fix IMAP breadcrumb (#13847)
closes https://github.com/twentyhq/twenty/issues/13811
figma -
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=72629-202079&t=CHbHe7QGamvPTnAi-0
2025-08-12 13:49:04 +02:00
d316f7edb9 fix: [Mailbox sync lost banner] Banner overlapping the filters (#13808)
Ignore `undefined` in the banner. I commented out the check for testing
purpose.


https://github.com/user-attachments/assets/f18b918b-b70b-4120-be36-96ba190c99be



/closes #13628

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-12 13:47:25 +02:00
Charles BochetandGitHub be8af1eb29 Migrate eslint to mjs (#13850)
Migrating eslint.config.js to eslint.config.mjs to remove ES error while
running linter
2025-08-12 13:12:03 +02:00
828be15405 i18n - translations (#13851)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-12 13:00:59 +02:00
8b59fcaea7 Remove preconstruct, update wyw (#13844)
To simplify our setup, moving back to Vite to build twenty-shared.

Also upgrading wyw

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-08-12 12:43:35 +02:00
Thomas TrompetteandGitHub 954da6da9d Delete filter on branch deletion (#13834)
When the target is not in the direct next step ids of the source (step
or trigger), check if there is a filter between both. If yes, delete the
filter and remove it from source next step ids.

Also refactored the existing.
2025-08-12 12:30:08 +02:00
Paul RastoinandGitHub d4b5ed93a3 FieldMetadataServiceV2.updateOne (#13784)
# Introduction
Implementing the `updateOne` service handler following workspace
migration v2 style
2025-08-12 10:05:53 +00:00
37a0f2726e Improve Stripe checkout to avoid redirecting to page (#13690)
It was painful to be redirected to an external site if you don't needed
to (no credit card needed)

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-08-12 11:49:08 +02:00
nitinandGitHub 8cb6053321 Add positions on company and person seeds (#13831)
addressing
https://discord.com/channels/1130383047699738754/1212034770792484934/1403352113865822279
2025-08-12 11:48:06 +02:00
GuillimandGitHub 63c8bb9530 morph backend CORE api (#13517)
# Morph Relation needs some work on the core API

Especially on the Morph types

<img width="682" height="394" alt="Screenshot 2025-07-31 at 12 19 40"
src="https://github.com/user-attachments/assets/8b185ae3-3fe7-4886-97b1-ec143bb1b0f4"
/>


## Focus Areas:
- GraphQL schema generation
- Query parsing and field selection
- Morph relation field support
- Input type definition preparation
2025-08-12 11:47:02 +02:00
6cc947ea01 Removed useRecordTable (#13837)
This PR removes useRecordTable barrel-hook and instead use the pattern
that enforces one hook per function.

This allows to have a easier to maintain React code with small dedicated
hooks.

This PR also improves the usage of those hooks by cleaning some logic
that calls them.

We introduce a new hook : `useRecordIndexIdFromCurrentContextStore` that
factorizes logic that was duplicated to retrieve the `recordTableId`.

Introduced `useHandleColumnsChange`, that saves table columns into view,
this could be discussed but is it isolated with a TODO comment so ok for
now.

Also lowered the coverage because not enough to cover with test here.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-12 10:52:27 +02:00
Lucas BordeauandGitHub 3a1c94147f Refactor usePersistField (#13775)
This PR introduces refactors and tradeoffs in the API around the events
of field input.

# Refactored usePersistField

The hook `usePersistField` has been refactored to be used anywhere in
the app, not just inside a FieldContext.

This was meant to solve a bug at the beginning but now it is just used
once in `RecordDetailRelationSection` outside of the context, still this
is better to have this hook like that for future use cases.

We also introduce `usePersistFieldFromFieldInputContext`, for an easier
API inside a FieldContext.

# Introduced a new `FieldInputEventContext`

To remove the drill-down of events, we introduce
`FieldInputEventContext`, this allows to set only once the handlers /
events. In practice it allows to have an easier time maintaining the
events for the many different field inputs, because it matches the
pattern we already use of taking everything from a context
(`FieldContext`).

# Removed drill-down from FieldInput

The heavy drill-down in FieldInput has been completely removed, since
everything can be derived from `FieldContext` and
`FieldInputEventContext`.

Also there was some readonly and other specific props, but they were all
drilled down from FieldContext, so it was easier to just use
FieldContext where needed.

# Refactored events of `MultiItemFieldInputProps` 

The component `MultiItemFieldInputProps` has a contrived API, here we
just remove the complex part that was persisting from inside.

We now only give a classic API with `onChange` and `onEscape` the rest
is left to higher levels, where it should be, because this generic
component shouldn't be aware of persisting things.

# Extracted the parsing logic of persisted values

For each input field component, we now have a clear util that was before
bound to the persist call,

# Tradeoff with persist times

The tradeoff before was that persistField was called anywhere, before
exiting the component sometimes, now it is only called by the higher
levels like table or show page, which handles this abstraction.

This could be challenged, however I think that having a lot of different
events, and not just `handleSubmit` and `handleCancel`, convey enough
meaning for the higher levels to decide what to do in each case.

A `skipPersist` argument was added in events in the rare edge cases
where we want to voluntarily skip persisting even with a submit or
escape, but that could be challenged because we could also say that we
should use cancel for that and stick to that convention.

# Handling of the bug in `ActivityRichTextEditor`

Initially this refactor was prioritized for solving this bug, which was
very annoying for the users.

But while fixing it with the new persistField hook I just understood
that the problem is not just for record title cells but for anything
that is open when we click on a rich text editor.

The issue is described here :
https://github.com/twentyhq/core-team-issues/issues/1317

So right now I just let it as is.

# Stories

The stories were checking that a request was sent in some cases where
persist was called before a component exiting, now that persist is only
called by higher-levels I just removed those tests from the stories,
because that should be the responsibility of higher levels.

Also a helper `getFieldInputEventContextProviderWithJestMocks` was
created that exposes a context and jest mock functions for testing this
new API in stories.

# Miscellaneous

Deactivated tui with nx by default, because it can be annoying.
2025-08-12 10:42:13 +02:00
Félix MalfaitandGitHub af2dace71c chore: scope package.json deps to packages (#13835)
- Move dev-only types to devDependencies
- Move frontend-only deps from root to twenty-front
- Add website-only deps to twenty-website
- Fix react-phone-number-input patch path

CI should validate.
2025-08-12 07:15:20 +02:00
Baptiste DevessierandGitHub 245e69e622 Prevent edges selection and deletion (#13830)
https://github.com/user-attachments/assets/5a3d5a4b-2d8e-418a-a638-09acd0b94d84
2025-08-11 19:06:34 +02:00
ac652842d6 i18n - translations (#13833)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-11 18:51:15 +02:00
GuillimandGitHub ce55809031 Text update (#13832)
Updating text after talking with @bonapara
2025-08-11 16:37:33 +00:00
4fa10a587d i18n - translations (#13828)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-11 17:48:07 +02:00
6314443c4f Adding Merge and IMAP Features to 1.3 Changelog (#13823)
## PR Summary 
- Added two new covers 
- Wrote their according feature description

---------

Co-authored-by: vickywxng <vw92@cornell.edu>
2025-08-11 17:47:45 +02:00
Baptiste DevessierandGitHub 3e5b60a923 Add Delete branch buttons (#13826)
Deleting branches containing a filter isn't yet supported by the
backend, but I set up the button in the frontend.



https://github.com/user-attachments/assets/f27234c4-ff9c-4f5c-930c-64d824981454
2025-08-11 17:38:22 +02:00
Félix MalfaitandGitHub 32cdb66802 Type fixes and website fix (#13825)
Various fixes
2025-08-11 17:36:53 +02:00
GuillimandGitHub 68ce13a1be lint config backend (#13827) 2025-08-11 17:27:56 +02:00
Thomas TrompetteandGitHub 5e93e5374a Add missing images to lab (#13824)
Add images for two factors and branches
2025-08-11 14:54:56 +00:00
Charles BochetandGitHub b55a48139c Remove hoisting on server (#13821)
Testing a different approach to fix broken buildPackageJson on server
build

How i have tested:

A. Local contributor setup
- run yarn
- build server
- run yarn workspace focus
- run server on dist

B. self-host
- docker build

Note: I think the dependencies I have added are suboptimized as the
image went from 2GB to 3.5GB. We might need to be more accurate
2025-08-11 15:58:05 +02:00
Charles BochetandGitHub b14063fe06 Re-add prettier (#13812)
Re add prettier in eslint.configs
2025-08-11 14:10:04 +02:00
Félix MalfaitandGitHub c8d8fb20c9 Fix start twenty-front not working with flat file config (#13816)
Use flat file config
2025-08-11 13:37:56 +02:00
Raphaël BosiandGitHub 7f36ec713e Fix core views enum names (#13805)
Fix core views enum names
2025-08-11 13:18:18 +02:00
Abdul RahmanandGitHub 9b11735c57 Code first roles sync (#13667) 2025-08-11 13:14:45 +02:00
Félix MalfaitandGitHub 2a2a2faadf Remove eslint-config-next from twenty-front (#13809)
This is for next.js not Twenty-front
2025-08-11 12:25:47 +02:00
Thomas des FrancsandGitHub 1b2987c5ff fixed changelog date parsing issue (#13806)
# Before

<img width="3450" height="2078" alt="CleanShot 2025-08-11 at 11 25
25@2x"
src="https://github.com/user-attachments/assets/a6b53846-8012-453a-9ff8-2fd51f2d9efd"
/>

# After

<img width="3456" height="2076" alt="CleanShot 2025-08-11 at 11 25
37@2x"
src="https://github.com/user-attachments/assets/1784ebd7-6040-4ab3-9ca6-26efd5d240a0"
/>
2025-08-11 12:14:43 +02:00
Félix MalfaitandGitHub d29dbd473b Upgrade SWC Core and Storybook to v8 (#13799)
This is is a blocker for various sub-migrations
2025-08-11 12:02:33 +02:00
Balaji KrishnamurthyandGitHub e6cb0c0a25 Sort object destinations in relation field (#13802)
Closes #13717
2025-08-11 11:38:49 +02:00
7b66d2a585 i18n - translations (#13798)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-10 23:32:57 +02:00
Félix MalfaitandGitHub 464a480043 Continue ESLINT9 Migration (#13795)
Might already fix #13793
2025-08-10 23:25:58 +02:00
df68cf98d4 i18n - translations (#13792)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-09 03:50:28 +02:00
Charles BochetandGitHub b55c46f4a3 Few fixes before release 1.3.0 (#13791) 2025-08-09 03:08:11 +02:00
1916333eac Seed core views at workspace creation (#13741)
Seed core views at workspace creation

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-09 01:00:42 +02:00
983c40485b Add destroy for core view resolvers (#13745)
Add destroy for core view resolvers

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-09 00:44:17 +02:00
12709481cf fix(webhook): clarify endpoint expects application/json payloads (#13786)
This PR updates the subtitle under the "Endpoint URL" input on the
webhook creation form.

The updated text clearly states that the server sends POST requests with
application/json and recommends setting the correct Content-Type.

This addresses issue #13757.

Closes #13757

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: ehconitin <nitinkoche03@gmail.com>
2025-08-08 19:33:49 +00:00
StephanieJoly4GitHubCharles Bochetgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
42336f1d23 user Guide - updating the csv export article (#13762)
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-08-08 20:43:38 +02:00
48e783c4fa fix(ui): remove line break in all IMAP section subtitles (#13785)
This PR removes the unintended line break in all IMAP section subtitles
so the text reads as a single inline paragraph.

 No functional changes  
 Purely UI/text formatting fix




Closes #13783

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-08 20:36:38 +02:00
41480dc64c i18n - translations (#13788)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-08 19:20:15 +02:00
martmullGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
bb5bd51209 Add workflow branches to lab (#13780)
as title

<img width="991" height="757" alt="image"
src="https://github.com/user-attachments/assets/7c7e042f-f616-40a6-8e82-3898a700b9da"
/>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-08-08 19:17:48 +02:00
e06fc34cbe Unique fields - add unicity toggle on data model settings (#13592)
To review after https://github.com/twentyhq/twenty/pull/13539

closes https://github.com/twentyhq/core-team-issues/issues/1224

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-08 19:15:49 +02:00
6a492b0732 i18n - translations (#13782)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-08 17:48:27 +02:00
EtienneandGitHub 7ce96049b8 Unique field - add unique property creation/deletion on field (#13539)
Done : 
- add isUnique prop availability on gql update/create fieldMetadata
resolvers
- add unique index creation logic at update & creation
- add unique index deletion logic at update
- update unique index if field name updated
- edge cases : can't have default value and unique fields / standard
default value excluded from index (where clause) / can't have composite
unique fields / can't create unique fields on MORPH


closes https://github.com/twentyhq/core-team-issues/issues/1222
2025-08-08 17:42:50 +02:00
martmullandGitHub 415f57ffa5 Fix qa issues with branches (#13776)
Fixes 3 issues:

- Can’t delete a trigger node if alone
- Workflow branch with Form terminates with Fail

<img height="350" alt="Pasted Graphic"
src="https://github.com/user-attachments/assets/a8cc1ebe-bf3f-4b7f-b3f1-a13c98408bc7"
/>
- If empty trigger with branch, it adds edges that does not exists on db
<img height="350" alt="Pasted Graphic 2"
src="https://github.com/user-attachments/assets/6642220b-9c7a-4efe-8cb3-c5d94fdd4dd5"
/>
2025-08-08 17:29:09 +02:00
8bd4dd2fd5 i18n - translations (#13778)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-08 16:37:22 +02:00
f2195225cf i18n - translations (#13777)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-08 16:26:20 +02:00
858391492b Docs and improve trigger icon handling (#13769)
<img width="1124" height="248" alt="image"
src="https://github.com/user-attachments/assets/6f35391b-0dd0-4129-ae94-b66f824533e6"
/>

#13757  and #13766

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-08 16:26:07 +02:00
Paul RastoinandGitHub 4523ee45bc Multiple errors on field input transpilation improvement (#13774)
# Introduction
- ~~returning deleted field on deleteOneField~~ postponed for later
cannot build dto from flat atm
- refactor createFieldInput transpilation to handle multiple errors
instead of throwing
- renamed extract function
2025-08-08 16:24:47 +02:00
Charles BochetandGitHub 7a90fb2c5f fix messaging (#13772)
Fixing a small mistake!
2025-08-08 16:22:53 +02:00
Félix MalfaitandGitHub 5fae14377a Eslint migration 4 (#13773)
A new attempt to migrate!
2025-08-08 16:21:57 +02:00
81012ab1fb Import - Unique value check optimization (#13761)
After an issue opened by @StephanieJoly4

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-08 16:19:34 +02:00
Thomas TrompetteandGitHub 59c508ab7b Add workflow filters to the lab (#13770)
As title
2025-08-08 13:59:00 +00:00
MarieandGitHub 2932439689 [permissions] Add field permissions feature flag in lab (#13767)
- Add field permissions feature flag in lab
- Fix / configuration of field permissions on roles page should be
behind feature flag (@lucasbordeau )
2025-08-08 13:42:50 +00:00
84df53467b i18n - translations (#13771)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-08 15:20:18 +02:00
Paul RastoinandGitHub 28e5186f23 FieldMetadataServiceV2.deleteOneField (#13744)
# Introduction
- Migrated the `deleteOneField` handler to new workspace migration v2
style
- Refactored the build to expect `flatObjectMetadataMaps` that he
instantly translate at the be beginning
Commented `ObjectMetadataServiceV2` as it's still not implemented
neither used
2025-08-08 15:11:47 +02:00
Félix MalfaitandGitHub 33f8885ef4 feat(nx-cloud): set up nx workspace (#13768)
feat(nx-cloud): setup nx cloud workspace

This commit sets up Nx Cloud for your Nx workspace, enabling distributed
caching and the Nx Cloud GitHub integration for fast CI and improved
developer experience.

You can access your Nx Cloud workspace by going to

https://cloud.nx.app/orgs/6895c992e7d4ba1786546b39/workspaces/6895ca12e7d4ba1786546b3c

**Note:** This commit attempts to maintain formatting of the nx.json
file, however you may need to correct formatting by running an nx format
command and committing the changes.
2025-08-08 12:02:19 +02:00
Thomas TrompetteandGitHub f9fa2db7f0 Display id field input as record picker (#13759)
When selecting a record or an id, a text input was appearing.
Replacing by a record picker. 

Before


https://github.com/user-attachments/assets/61e7c1fe-4f74-459e-8b50-5ebe2fc7462f

After


https://github.com/user-attachments/assets/ad7fcf05-b86c-4e10-a8cb-bd3e4a694812
2025-08-08 12:01:17 +02:00
Félix MalfaitandGitHub 033bedde0a Upgrade NX (#13758)
Upgrade from NX18 to NX21
2025-08-08 10:38:12 +02:00
MarieandGitHub 4708ff34c7 [permissions] Fix update of relation field permissions (#13755)
In this PR, we add some validation logic and rules in both FE and BE to
ensure field permissions are handled correctly for relation fields.

- (BE) Only one field permission per fieldMetadata is accepted per
input. This is already guaranteed in the FE. It was added to help
guarantee that, when looking within the field permissions input for a
potential field permission on a relationTargetFieldMetadataId for a
relation field, there can only be 0 or 1.
- (FE) Only field permission with new values are sent to save, to avoid
sending contradictory field permissions for related fields. E.g. let's
say I have an existing field permission restricting read permission on
company's people field. By definition I also have one on person's
company field. If I update this field permission to enable the read
permission by updating company's people field, in the previous logic I
was also going to send for upsert the existing obsolete field permission
on person's company. Thus the server does not know which is the right
value so we should only send the new value.
- (BE) If the server receives two contradictory field permissions on two
related fields, e.g. on company's people with canRead = null and
person's company with canRead = false, it throws an error.
2025-08-08 08:27:53 +00:00
Félix MalfaitandGitHub 0236f79ccf Fix assert unreachable, remove unused variables (#13753)
Small code cleanup
2025-08-08 09:04:45 +02:00
Félix MalfaitandGitHub 8b4b9ef8da Change type import rule (#13751)
Forcing "type" to be explicit, works best will rollup on the frontend to
exclude depdendencies
2025-08-08 01:27:05 +02:00
Charles BochetandGitHub 525c8bfe3c Other messaging improvements (#13750) 2025-08-08 00:19:22 +02:00
Charles BochetandGitHub 5c7829c19a Improve messaging batch (#13747)
When users have more than 100k messages, this part is also starting to
slow down
2025-08-07 22:45:19 +02:00
Félix MalfaitandGitHub b44b46109c Update try/catch syntax (#13732)
Update try/catch syntax to prepare for eslint migration
2025-08-07 22:19:43 +02:00
Charles BochetandGitHub 4baabd80ef Improve messaging behavior (#13746)
This PR contains multiple small enhancements
2025-08-07 20:21:18 +02:00
Thanish NizamandGitHub 6c2e11f830 Run migrations on empty databases on docker compose (#13647)
It is possible an empty database might already with the configured name.
Check whether the core schema exists and run migration scripts if it
doesn't.

For example, some may prefer creating a postgres database and user and
assigning the user access only to that specific database.
2025-08-07 19:04:44 +02:00
martmullandGitHub 713c3d71fb Add command to delete workflow runs (#13736)
Add `workflow:delete-workflow-runs` command to delete workflow runs
Options:
- created-before YYYY-MM-DD default to now
- standard options from
`ActiveOrSuspendedWorkspacesMigrationCommandRunner` commands
2025-08-07 19:03:11 +02:00
6fa34df6f9 i18n - translations (#13738)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-07 18:51:17 +02:00
593b064448 Create resolvers and controllers for core views (#13624)
Created:
- Services
- Resolvers
- Controllers
- Tests for services
- Integration tests for GraphQL and Rest

Updated the Rest API playground

Added new feature flag `IS_CORE_VIEW_ENABLED`

Updated `viewFilter` `operand` and `view` `type` to be enums rather than
strings and generated migration file.

Closes https://github.com/twentyhq/core-team-issues/issues/1259

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-07 18:45:04 +02:00
EtienneandGitHub caabe8738d fix rest api metadata (#13720)
Introduce in [MCP Metadata
PR](https://github.com/twentyhq/twenty/pull/13150/files#diff-1c17892e6bc91125638b0cc195ab9f4661c39042e36a6eaac95a83f32d1f70bdR4)

[Fix issue opened in Discord

](https://discord.com/channels/1130383047699738754/1155864201068286043/1402921467468972032)
2025-08-07 18:30:33 +02:00
Paul RastoinandGitHub 5476164a28 Expect node 24.5.0 (#13734)
Unless I'm mistaken the project does not run with node `24.0.0`
Switching to node `24.5.0` ( as defined in vscode node runtime
requirements in https://github.com/twentyhq/twenty/pull/13730 ) seems to
fix the issue
```ts
Successfully compiled: 2897 files with swc (188.32ms)
(node:77006) [DEP0190] DeprecationWarning: Passing args to a child process with shell option true can lead to security vulnerabilities, as the arguments are not escaped, only concatenated.
(Use `node --trace-deprecation ...` to show where the warning was created)
Watching for file changes.

/Users/paulrastoin/ws/twenty/node_modules/buffer-equal-constant-time/index.js:37
var origSlowBufEqual = SlowBuffer.prototype.equal;
                                  ^
TypeError: Cannot read properties of undefined (reading 'prototype')
```

Updating engines so local constraint suggest a functional node version
2025-08-07 16:22:28 +00:00
ee19ee5119 [permissions] QA fixes (#13698)
In this PR

- Introduction of readableFields and updatableFields in
objectMetadataItem selector to ease filtering from a developer
experience perspective ( + to help developers think to do it). In
discussion @lucasbordeau @charlesBochet
- Remove non-updatable field from CSV import process (@etiennejouan)
- QA fix / Non-readable fields should not show on show page
- QA fix / It should not be offered to create a kanban view on a
non-readable field
- QA fix / It should not be offered to create view groups on a
non-readable field
- QA fix / Rating field should have a readonly mode

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-07 18:21:59 +02:00
Thomas TrompetteandGitHub 258f21a4be Prevent node creation when trigger is empty (#13731)
Before


https://github.com/user-attachments/assets/5d411abe-a480-4c51-8357-9dc710e23792

After


https://github.com/user-attachments/assets/2dd551b2-6f84-4129-8cc0-7af82aba5e8e
2025-08-07 15:41:15 +00:00
Thomas TrompetteandGitHub 385e0253ed Remove filter when this is the last step (#13726)
As title


https://github.com/user-attachments/assets/b5cf6168-31d1-4f9f-b661-b00ea557ce8a
2025-08-07 17:19:23 +02:00
Paul RastoinandGitHub 83a560c936 Refactor FieldMetadataService and validation to consume FlatObjectMetadataMaps (#13719)
# Introduction
Following recent `FlatObjectMetadataMaps` manipulation, transpilers
utils introduction in https://github.com/twentyhq/twenty/pull/13620
Refactored the field metadata service and validator to iterate over
`FlatObjectMetadataMaps` instead of `FlatObjectMetadata[]`.

The object metadata service v2 is shadow coding
2025-08-07 17:19:07 +02:00
Félix MalfaitandGitHub 05c6805f0a Upgrade to Node 24 (#13730)
As described in title
2025-08-07 17:02:12 +02:00
Félix MalfaitandGitHub a27dc5ddf1 Remove chrome extension (#13729)
We'll bring it back later
2025-08-07 16:32:34 +02:00
Thomas TrompetteandGitHub 3e1c9295d9 Do not throw when no selected not found (#13727)
<img width="1299" height="713" alt="Capture d’écran 2025-08-07 à 15 25
23"
src="https://github.com/user-attachments/assets/b9c3c3d3-9521-442a-8493-54a06418ade0"
/>

Remove error from console. When deleting a step, we get the command menu
opened for a short time. We should simply return null until the command
menu gets closed

Fix
https://twenty-v7.sentry.io/issues/6795046867/?project=4507072563183616&referrer=github-open-pr-bot
2025-08-07 16:17:52 +02:00
Baptiste DevessierandGitHub 0822080105 Set flow after step creation (#13725)
## Before


https://github.com/user-attachments/assets/5f89e2c5-af59-46eb-a0af-6eb0ab103291

## After


https://github.com/user-attachments/assets/11accdc5-a49c-4479-8686-b01f44519d81

## The issue

`getStepDefinitionOrThrow` throws if the provided `steps` aren't
defined. With my recent refactor, the side panel is opened immediately,
as we no longer open it in the `useOnSelectionChange` hook. We use a
`useEffect` to set the `flowState` whenever the workflow version
definition changes. As the side panel is now opened faster,
`getStepDefinitionOrThrow` throws before the `flowState` could have been
set.

In this PR, I only fixed the bug I encountered. We might want to replace
the synchronization `useEffect` with explicit `setFlow` calls whenever
we change the workflow version.
2025-08-07 15:32:37 +02:00
martmullandGitHub 8a246b5422 Fix missing WHERE clause in migration (#13718)
As title, this has been run in production and all the workflow runs have
been updated with the last workflow run data
2025-08-07 14:12:44 +02:00
nitinandGitHub d1be33a759 fix record position calculations on tables (#13723)
closes https://github.com/twentyhq/twenty/issues/13722
2025-08-07 14:07:12 +02:00
MarieandGitHub 05c23a1297 [permissions] Fix delete and soft-delete + enable fieldPermissions in devSeeds (#13646)
In this PR
1. Fix delete and soft-delete repository methods for repositories where
permission checks are NOT bypassed: they need to have a selection of
columns to return by default. To match what we did for insert I set it
to `'*'` by default. But I feel this may be bug prone as developers will
not necessarily think to fill the right values in. Maybe we should
change the api to use selectable fields by default. @charlesBochet
2. Add field permission seeds and enable field permission feature flag
in dev
2025-08-07 10:43:28 +02:00
Thomas TrompetteandGitHub 9cfd62f1ef Filter dropdown by types (#13703)
Allow to filter types in variable dropdown. This will avoid unsupported
types for filters (RICH_TEXT, ACTOR)
<img width="579" height="505" alt="Capture d’écran 2025-08-07 à 09 58
42"
src="https://github.com/user-attachments/assets/c3fbeb3f-61ab-4c2c-bb2c-6f2c6292ef9e"
/>
2025-08-07 10:38:46 +02:00
Charles BochetandGitHub 6e4e623303 Fix update many behavior with composite and connect (#13712)
We had two mistakes in updateMany orm behavior:
- format of manyInput should be done earlier
- relation connect/disconnect does not support batching and should be
computed for each input at last moment
2025-08-07 09:49:58 +02:00
Thomas TrompetteandGitHub 8c41c956d5 Remove filters following deleted trigger/steps (#13697)
https://github.com/user-attachments/assets/e6ec591a-2064-4dfe-9048-2f234bef5c79
2025-08-07 09:40:26 +02:00
Charles BochetandGitHub fecf8ca913 Fix i18n issues on datamodel translation (#13710)
As per title, I believe calling i18n is bad because it's a singleton.

This singleton is being set back and force by users in
i18n.middleware.ts

Strategy:
we need to load the translations dynamically! Should be straight
forward:
- singleton (i18nService) containing all translationMessages
- singleton also containing a map of i18n instances loaded for each
locale => I've checked it's not heavy on RAM at all
- some methods to get the translation for a messageId x locale or the
whole i18n instance

==> use it everywhere, this PR only takes care of data model translation
2025-08-07 01:28:40 +02:00
58d25ebd83 CreateMany optim - .save -> .updateMany + position (#13704)
fixes : https://github.com/twentyhq/core-team-issues/issues/1312

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-07 00:52:28 +02:00
EtienneandGitHub 723f1016a6 Timestamp column migration in all workspace schema tables (#13679)
fixes https://github.com/twentyhq/private-issues/issues/288

Test with : 
`npx nx run twenty-server:command
upgrade:1-3:update-timestamp-column-type-in-workspace-schema`
2025-08-06 22:12:52 +02:00
EtienneandGitHub e857860e21 [Need metadatada sync] - add user email unique on workspace member (#13686)
fixes : https://github.com/twentyhq/core-team-issues/issues/1311

>
https://discord.com/channels/1130383047699738754/1402588108947460207/1402594885995069522
2025-08-06 22:11:50 +02:00
Charles BochetandGitHub 5631dd122e Refactor timeline activity insert (#13696)
In this PR:
- refactor timelineActivity computation to batch it
- make sure to pass the authContext to insert-query-builder in order to
pass user information to timelineActivity
- refactor message-participant /calendar-participant creation to batch
more
- fix favorite on view race condition (FE)
- deprecate PARTIAL_CALENDAR_EVENT_FETCH_LIST syncStage as we will
deprecate partial vs full notion (we will just leverage cursor emptyness
or not)
- introduce calendar / messging SCHEDULED syncStage that will allow
better performance granularity later
- activate quick message import after message list fetch to speed
performance on small message lists
2025-08-06 22:11:26 +02:00
Félix MalfaitandGitHub 453a6167a5 PR comment followups (isNonEmptyString and rename WorkflowExecutionResult) (#13706)
Addressing two comments from Thomas and Charles
2025-08-06 22:09:30 +02:00
Paul RastoinandGitHub eab72d8e67 FlatObjectMetadataMaps utils coverage (#13695)
# Introduction
```ts
 PASS   twenty-server  src/engine/metadata-modules/flat-object-metadata-maps/utils/__tests__/add-flat-field-metadata-in-flat-object-metadata-maps-or-throw.spec.ts
 PASS   twenty-server  src/engine/metadata-modules/flat-object-metadata-maps/utils/__tests__/delete-field-from-flat-object-metadata-maps-or-throw.spec.ts
 PASS   twenty-server  src/engine/metadata-modules/flat-object-metadata-maps/utils/__tests__/find-flat-field-metadata-in-flat-object-metadata-maps.spec.ts
 PASS   twenty-server  src/engine/metadata-modules/flat-object-metadata-maps/utils/__tests__/replace-flat-object-metadata-in-flat-object-metadata-maps-or-throw.spec.ts
 PASS   twenty-server  src/engine/metadata-modules/flat-object-metadata-maps/utils/__tests__/replace-flat-field-metadata-in-flat-object-metadata-maps-or-throw.spec.ts
 PASS   twenty-server  src/engine/metadata-modules/flat-object-metadata-maps/utils/__tests__/find-flat-object-metadata-in-flat-object-metadata-maps.spec.ts
 PASS   twenty-server  src/engine/metadata-modules/flat-object-metadata-maps/utils/__tests__/add-flat-object-metadata-to-flat-object-metadata-maps-or-throw.spec.ts
 PASS   twenty-server  src/engine/metadata-modules/flat-object-metadata-maps/utils/__tests__/delete-object-from-flat-object-metadata-maps-or-throw.spec.ts

=============================== Coverage summary ===============================
Statements   : 0.43% ( 159/36564 )
Branches     : 0.16% ( 26/16182 )
Functions    : 0.27% ( 25/9110 )
Lines        : 0.4% ( 142/35006 )
================================================================================

Test Suites: 8 passed, 8 total
Tests:       20 passed, 20 total
Snapshots:   9 passed, 9 total
Time:        7.639 s
```

## Tests utils
Introduced three tests utils:
- expect-flat-field-metadata-to-be-in-flat-object-metadata-maps.util
-
expect-flat-object-metadata-to-strictly-be-in-flat-object-metadata-maps.util
- expect-to-be-defined.util
2025-08-06 17:27:36 +00:00
d45fcf43e5 i18n - translations (#13707)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-06 19:21:03 +02:00
Baptiste DevessierandGitHub b8cd4491c2 Replace useOnSelectionChange with onClick listeners for steps opening (#13672)
This PR cleans a few parts of the workflow features and fixes a few
improper behaviors.

Here is a non-exaustive list of improved things:

- Clicking on an action will always reset the command menu's navigation
stack. Previously, the behavior wasn't unified between workflows,
workflow versions and workflow runs.
- Opening a step in the side panel is now down in the `onClick` event
handler put on individual Reactflow nodes. This makes interoperability
between filters (which are buttons on edges) and traditional actions.
- Simplified the code that automatically opens pending forms in the side
panel. This feature should now work more predictably.
- Splitted the `WorkflowDiagramEmptyTrigger` component into
`WorkflowDiagramEmptyTriggerEditable` and
`WorkflowDiagramEmptyTriggerReadonly`. This makes handling events easier
as the behavior isn't the same in both cases.
- Dropped all `useOnSelectionChange` hooks that were used to open steps
in the side panel upon user selection.
- Created a specific `WorkflowRunDiagramStepNode` instead of using
`WorkflowDiagramStepNodeReadonly` in `WorkflowRunDiagramCanvas`
- Deleted `useHandleWorkflowRunDiagramCanvasInit` as it was used to open
the initially selected step in the command menu, which is now handled in
an effect that works for all cases, including workflow run's state
refreshing.

Closes https://github.com/twentyhq/core-team-issues/issues/1227
Closes https://github.com/twentyhq/twenty/issues/11923
2025-08-06 19:00:48 +02:00
martmullandGitHub 787f8b75ab Add design when edge focused (#13687)
Fix focused design for edges, edge buttons and handle

## Before
<img width="3014" height="1026" alt="image"
src="https://github.com/user-attachments/assets/8ef6647b-1ba6-4c71-9ffd-f6f5fe15e891"
/>


https://github.com/user-attachments/assets/9d702a24-70c4-4f2b-9655-5fec0f83e9d8


## After

<img width="1509" height="595" alt="Capture d’écran 2025-08-06 à 14 58
54"
src="https://github.com/user-attachments/assets/7c81b504-69a3-4d62-b455-738764b21d45"
/>



https://github.com/user-attachments/assets/7d859d12-c2e1-43d5-a611-d906aa9bc0d1
2025-08-06 17:47:35 +02:00
Paul RastoinandGitHub b71e6b0609 FlatObject/FieldMetadata and FlatObjectMetadataMaps mocks (#13691)
# Introduction
As discussed with Charles we will introduce a new command to convert
seeded twenty instance into `flatObjectMetadatas` `flatFieldMetadatas`
mocks but later.
We can think of this PR as a partial freeze of this command result run
even tho the template might not be strictly the same in the end.
For the moment we only extracted few objects with their fields in order
to start testing newly introduced tools

used scripts ( not committed and written on the fly ):
https://gist.github.com/prastoin/bdfae0da1e3e9c66ae21c972afbd0d1e
https://gist.github.com/prastoin/30029989bf57de9303e3f7ec235271ee
2025-08-06 17:10:09 +02:00
martmullandGitHub 040fde459a Disable node dragging on workflow run and workflow version (#13693)
As title

## Before


https://github.com/user-attachments/assets/f3d07bb8-5d8b-43de-b06d-ecd747e91b31



https://github.com/user-attachments/assets/8617ac1c-841d-4945-b8a9-e5052fdb5f2b



## After


https://github.com/user-attachments/assets/4549974b-e699-4756-8479-8ee27608692b



https://github.com/user-attachments/assets/2a1aa0f3-89c3-4769-82d3-da01dfe96170
2025-08-06 17:03:23 +02:00
Lucas BordeauandGitHub c48d14715c Fixed show page crash with object metadata item not found (#13694)
This PR fixes a bug that appeared because of a race condition with
context store when navigating between settings page and show page.

The bug was caused because record title cell used on record show page
was trying to retrieve the object metadata item before the context store
was initialized.

I created a new hook that supports an undefined state for one render
loop, since in that case components can be rendered before the context
store is initialized.

Fixes https://github.com/twentyhq/twenty/issues/13649
2025-08-06 14:41:06 +00:00
3db6d49e86 Fix for Invalid URL Error when creating new user (#13689)
Closes #13676

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-08-06 14:27:43 +00:00
Paul RastoinandGitHub ca3383cd86 Feat workspace migration maintains flat object metadata maps (#13620)
# Introduction
The workspace migration runner v2 now computes the next
flatObjectMetadataMaps post current ws migration action has been run
So the following one have an up to date informations

## Still TODO
~~Remove any contextual information from workspace migration v2 and
consume the optimistic cache to retrieve them~~

## Next steps
- Create flat-object-metadata-maps testing toolbox and flat-object/field
testing toolbox
- Implement strong coverage on every created utils/transpiler and
applyWorkspaceMigrationAction method
2025-08-06 13:10:14 +00:00
e1d169e51e i18n - translations (#13688)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-06 15:06:13 +02:00
Thomas TrompetteandGitHub d9dbfc4f7e Handle relations for filters (#13654)
- Refacto variable dropdown so it can display both objects and fields
- we do not filter on object name anymore to simplify the code
- add relation handler in filters



https://github.com/user-attachments/assets/e4f03f11-45cb-4d3f-b628-e996129dd996
2025-08-06 14:57:10 +02:00
Félix MalfaitandGitHub d74bcbe62b Fix broken main branch (#13685)
Main branch had changed in the meantime and these components had been
deprecated
2025-08-06 14:33:09 +02:00
25c4af8feb i18n - translations (#13684)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-06 14:01:47 +02:00
ca19b731ef Add ADD NEW cta as the last row (#13594)
<img width="961" height="478" alt="Screenshot 2025-08-04 at 14 34 07"
src="https://github.com/user-attachments/assets/42e266d2-7329-4eb7-9d22-78402800f646"
/>

---------

Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
2025-08-06 13:49:03 +02:00
nitinandGitHub a3322745b5 revert ci changes on ci-breaking-changes (#13682)
<img width="990" height="513" alt="Screenshot 2025-08-06 at 16 27 36"
src="https://github.com/user-attachments/assets/23a99dab-09cf-4978-8c10-5d8a2f7a84c9"
/>
2025-08-06 16:30:00 +05:30
nitinandGitHub 60257a9701 fix api mismatch on rest metadata (#13680)
## Context

This PR fixes a REST API metadata schema mismatch that occurred after
the webhook and apiKey migration from workspace entities to metadata
level.

## The Issue

After PR #13576 deleted the webhook and apiKey workspace entities, the
metadata OpenAPI specification ended up in a broken state:
- The `/metadata` endpoints still had paths for `/webhooks` and
`/apiKeys`
- But the schema definitions were missing (they were previously pulled
from workspace entities)
- This created dangling references in the OpenAPI document

## The Fix

Added proper schema definitions for webhook and apiKey directly in
`computeMetadataSchemaComponents`:
- `Webhook`, `WebhookForUpdate`, `WebhookForResponse`
- `ApiKey`, `ApiKeyForUpdate`, `ApiKeyForResponse`

## Why the CI is Failing

The CI breaking changes detection is comparing:
- **Main branch**: Has a broken OpenAPI document with endpoints that
reference non-existent schemas
- **This branch**: Has the fixed OpenAPI document with proper schemas

The OpenAPI diff tool can't even parse the main branch's document due to
the missing schema references, hence the error -- tested locally
2025-08-06 16:15:05 +05:30
neo773andGitHub 8169ba10a5 Merge record UI fixes (#13678)
Partially addresses #13643
2025-08-06 12:16:26 +02:00
Félix MalfaitandGitHub b7022202fa Introduce a TAB to test the HTTP node (#13622)
<img width="1020" height="757" alt="Screenshot 2025-08-05 at 11 05 12"
src="https://github.com/user-attachments/assets/7cfcb216-d34d-4daa-b468-8153869c8f6a"
/>
2025-08-06 12:12:13 +02:00
Lucas BordeauandGitHub de802b1447 Removed all v2 in naming of state management logic (#13675)
This PR removes any V2 naming in state management logic and some minor
utils and hooks.

It has a lot of changes but nearly all of them were made by the rename
functionality of vscode which is deterministic, so it shouldn't
introduce any regression.

QA has been made on this PR on the main features of the app without any
noticeable issue.

Also renamed some other v2 naming related items : 
- TextInputV2 => TextInput
- TextInput => SettingsTextInput
- ObjectFilterDropdownFilterSelectMenuItemV2 =>
ObjectFilterDropdownFilterSelectMenuItem
- useInitDraftValueV2 => useInitDraftValue
- useOpenRecordTableCellV2 => useOpenRecordTableCell
2025-08-06 12:09:15 +02:00
EtienneandGitHub d8b24812b0 Data model settings - Address field design fix (#13677)
fixes https://github.com/twentyhq/twenty/issues/13671

After
<img width="549" height="536" alt="Screenshot 2025-08-06 at 10 48 17"
src="https://github.com/user-attachments/assets/484bcaba-1538-4f20-9f87-cb71c72d1023"
/>
2025-08-06 11:28:43 +02:00
MarieandGitHub 9957057d1f [permissions] Adapt field permissions to connect + createMany (#13655)
In this PR we adapt field permission to two things

1. Connect: the recent insertion of the connect feature introduces the
possibility to have "connect" objects in typeORM's expressionMap's
valueSet, where we previously only had column names (if i followed
correctly). For instance for a person object that a N - 1 relationship
to company, person will have both companyId and company as possible
valueSet keys for the upsert. We need to reflect that in our
`getColumnNameToFieldMetadataIdMap` util that returns a map containing
every possible value we could encounter in valueSet. In an attempt to
tie this to the schema generation where this is introduced, I created
the shallow util extractGraphQLRelationFieldNames (probably ill-named -
im willing to update the name if @etiennejouan has a better idea?) to
remind us that these two are linked.

2. CreateMany: When calling query builders methods directly on custom
object (like we do in graphql-create-many-resolver), we need to be
careful to call them with a selection of readable fields. We had a
debate on whether we should compute this selection containing all
readable fields by default under the hood when no selected fields are
indicated. I am still not 100% convinced as I think it should remain the
caller's responsibility, but this case reminds us that it could easily
be forgotten by developers - although it is all the more the case as we
don't have seeds yet that help us realize that ([PR on the
way](https://github.com/twentyhq/twenty/pull/13646)).
2025-08-06 08:31:52 +00:00
neo773andGitHub a804d65210 add userFriendly messages to PermissionsException (#13659)
/closes #13580

<img width="1186" height="754" alt="image"
src="https://github.com/user-attachments/assets/d5be9e3a-2748-4ad0-b29b-98038cbeeb6a"
/>
2025-08-05 20:41:51 +00:00
neo773andGitHub 22eedb0281 Merge Records fix (#13658)
/closes #13643
2025-08-05 22:34:23 +02:00
Charles BochetandGitHub 4772523edd Fix insert query builder not handling empty array (#13656) 2025-08-05 20:29:48 +02:00
Lucas BordeauandGitHub a3aabc6855 Fixed SettingsObjectFieldItemTableRow grid sizes (#13653)
This PR fixes a wrong change that happened during a refactor of some
tables in the settings permission area.

**Before**

<img width="662" height="657" alt="image"
src="https://github.com/user-attachments/assets/a3cf5ce1-4aaa-410c-ac5f-d085b590554d"
/>


**After** 

<img width="661" height="660" alt="image"
src="https://github.com/user-attachments/assets/5eefb129-5fd6-497b-ba2a-5efc0851172e"
/>
2025-08-05 17:03:36 +02:00
martmullandGitHub 0bef766f63 Display edge button when whole edge is hovered (#13651)
As title

## Before
Need to aim center of edge


https://github.com/user-attachments/assets/5f014f15-af7b-4884-902d-3b7001782d2d


## After
Whole edge triggers hover behavior


https://github.com/user-attachments/assets/bddaa6b2-7d62-428a-bee5-c237db16a403
2025-08-05 14:53:08 +00:00
c60da685f7 i18n - translations (#13648)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-05 16:21:51 +02:00
Charles Bochet 345e98e557 Re add graphql middlware 2025-08-05 16:16:16 +02:00
martmullandGitHub 44f5600300 Split workspace service (#13642)
Splits workflow-version-step workspace-service into multiple once
2025-08-05 14:10:11 +00:00
Charles BochetandGitHub d62a1e0b5a Re add graphql middlware (#13644) 2025-08-05 15:57:37 +02:00
MarieandGitHub 46e43a62c4 [permissions] Handle fieldPermissions configuration for 1N relations (#13630)
When upserting a fieldPermission on a 1 <-> N relation field, we should
upsert the same fieldPermission on the relationTargetFieldMetadata to
avoid inconsistencies.
2025-08-05 15:48:39 +02:00
287edd44ad i18n - translations (#13645)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-05 15:47:31 +02:00
Félix MalfaitandGitHub 1de3338551 Improve code editor style and enable full screen code editor (#13618)
<img width="1501" height="757" alt="Screenshot 2025-08-05 at 09 30 44"
src="https://github.com/user-attachments/assets/535e6dfb-a1b5-4812-b5a9-c19ab7bb7240"
/>
<img width="486" height="717" alt="Screenshot 2025-08-05 at 09 30 36"
src="https://github.com/user-attachments/assets/189407b3-fdec-4795-b115-7e00a11e6bc5"
/>
2025-08-05 15:38:54 +02:00
martmullandGitHub 4ccd9e21e7 Fix workflow run command (#13641)
as title
2025-08-05 15:36:44 +02:00
Charles BochetandGitHub 90151425ac Remove graphql-middleware (#13638)
Graphql middleware is not used anymore in the project directly. However
it's a peer dependency of other graphql packages. This leads to a
conflict in our docker image
2025-08-05 15:11:30 +02:00
fe3cce8a1d i18n - translations (#13636)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-05 15:06:14 +02:00
nitinandGitHub 111f083a24 [api keys] fix breadcrumb not appearing on api key details (#13633) 2025-08-05 14:37:11 +02:00
Charles BochetandGitHub db00fb6a50 Add immer in package.json (#13635) 2025-08-05 14:34:20 +02:00
EtienneandGitHub 010c9b6250 fix typo (#13634) 2025-08-05 14:34:10 +02:00
Charles Bochet 6da416e27d Add apiKey upgrade command to 1.3 2025-08-05 14:25:31 +02:00
f27c650bc2 i18n - translations (#13632)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-05 14:22:55 +02:00
Charles BochetandGitHub 16d78b450c Fix email not verified issue while login through sso (#13631)
In this PR:
- fix race condition while getting token and redirecting to workspace
domain (missing await)
- add userFriendlyMessage when user does not have password and we try to
log in using password
- refactor computePartialUserFromUserPayload to remove side effect
- add isEmailAlreadyVerified in userPayload that will set
user.isEmailVerified to true
2025-08-05 12:01:55 +00:00
dcded4ae4f i18n - translations (#13627)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-05 12:01:18 +02:00
Thomas TrompetteandGitHub 6abef38993 Handle types that are not field metadata (#13604)
Some steps that do not return field metadata types need to be handled
2025-08-05 09:54:06 +00:00
Lucas BordeauandGitHub 04ed843aaf Field permission CRUD front-end implementation (#13524)
This PR implements what's needed to edit field permissions on a role.

Field permissions that aren't useful are kept in the database to avoid
the overhead of adding cleaning logics both in front end and back end.
They just won't be taken into account if object permission doesn't allow
it.

In this PR we also handle the case were there's no object permission
override but where there are only field permission overrides, which can
happen if an object inherits from a "all object can read" but restricts
read only on some fields.

<img width="547" height="642" alt="image"
src="https://github.com/user-attachments/assets/77d81f89-4af9-42b6-97f3-fae3a6ba1eeb"
/>


<img width="590" height="912" alt="image"
src="https://github.com/user-attachments/assets/69fab8ee-7252-401a-bc6f-8a8b7c7f6bc4"
/>

Fixes https://github.com/twentyhq/core-team-issues/issues/1152

This PR lowers unit test coverage because the essential unit tests for
this PR have been written and writing more tests would not be a great
tradeoff for this feature which has already taken a lot of efforts.
2025-08-05 11:50:23 +02:00
martmullandGitHub 497fc2c0b2 Fix created step position (#13621)
This PR fixes create floating step position and insert step position in
workflow run when featureFlag IS_WORKFLOW_BRANCH_ENABLED is true

## Before


https://github.com/user-attachments/assets/eecef0f5-d2b1-468d-b3c1-0755db1f8278


https://github.com/user-attachments/assets/9995c7d4-c005-4d1f-8e3b-c624d05da32d




## After



https://github.com/user-attachments/assets/c6faa1d7-0b3f-473b-bdfe-67a2e08397d8


https://github.com/user-attachments/assets/c89fed0c-2bd5-42b6-956c-c62c297e0146
2025-08-05 11:25:20 +02:00
Paul RastoinandGitHub 6af99ab1ea FlatObjectMetadataMaps and non FP style refactor (#13590)
# Introduction
- Retrieveing flat-object-metadata-maps for input transpilation, we
decided not to introduce map merge for remaining validation operation
for the moment
- Refactored the field metadata service v2 to sequentially
optimistically render on each iteration
2025-08-05 08:46:28 +00:00
nitinandGitHub ca9464e19d [Admin Panel] fix invalid uuid issue on health status (#13619)
Health status queries are failing at the moment - regression was
introduced in 01f25519f6
health status ids are not uuids, we use params to fetch them on the
frontend.
But maybe @FelixMalfait and @abdulrahmancodes have more context on this
one?
2025-08-05 08:09:07 +00:00
9ceb097ab7 IMAP Fixes & Improvements (#13582)
- Removed caching of IMAP client as it was problematic and didn't really
matter because of our pipeline, also added retry logic to client.
- Some code refactoring and cleanup
- Breaking changes:
   - Removed messageChannel.syncCursor
   - Uses messageFolder.syncCursor instead
- Removed Date based sync cursor in favor of message UID which is much
more reliable and precise

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-05 09:46:28 +02:00
ca6322cae6 i18n - translations (#13617)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-05 09:21:57 +02:00
nitinandGitHub 676cf838af [CleanUp] Post api keys and webhooks migration cleanup (#13576) 2025-08-05 12:43:09 +05:30
df9136c6c0 i18n - translations (#13616)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-05 08:02:14 +02:00
Abdul RahmanandGitHub b2452e83ad Fix soft delete unique constraints to allow reusing unique values after deletion (#13615)
Closes [#1297](https://github.com/twentyhq/core-team-issues/issues/1297)
2025-08-05 07:57:02 +02:00
Félix MalfaitandGitHub ade7f8b6ae Update object-level permissions design (#13614)
<img width="569" height="448" alt="Screenshot 2025-08-05 at 07 25 15"
src="https://github.com/user-attachments/assets/3bd628ed-e79e-4850-a24c-002e6cb246e7"
/>
<img width="549" height="441" alt="Screenshot 2025-08-05 at 07 25 26"
src="https://github.com/user-attachments/assets/0941541c-d28b-4c17-98ee-1d8fb0c47f6b"
/>

I did keep the empty state + "object rule" instead of rule for clarity
2025-08-05 07:51:18 +02:00
neo773andGitHub 19dbe28786 feat: email and calendar events for opportunities (#13613) 2025-08-04 21:43:09 +00:00
2a0c73d276 Add snackbar on CSV exports (#13608)
#13516 

Add the snackbar on CSV exports



https://github.com/user-attachments/assets/d8288351-66f1-4175-814e-ecf0f5b57274

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-08-04 23:33:00 +02:00
Félix MalfaitandGitHub d3fc1cd837 Remove unused dependencies (#13611)
Cleaning up unused dependencies
2025-08-04 22:44:24 +02:00
Félix MalfaitandGitHub 7383b0935c Remove unused files (#13612)
Remove a few unused files
2025-08-04 22:35:36 +02:00
Félix MalfaitandGitHub 69f2f94f50 Upgrade Vite6 to Vite7 (#13610)
As described in title
2025-08-04 22:01:32 +02:00
alexcohfrandGitHub b10e7ef642 Update docker-compose.mdx (#13597)
Changes on the self-hosting tutorial to match env variables of the
actual docker-compose file and .env.example
2025-08-04 19:07:44 +02:00
EtienneandGitHub 3c485ccb37 Upsert in CreateMany - fixes (#13598)
fixes https://github.com/twentyhq/twenty/issues/13553
and https://github.com/twentyhq/core-team-issues/issues/1300
2025-08-04 19:06:40 +02:00
932910e71e Refactor isReadOnly + introduce restrictedFields (#13533)
Closes https://github.com/twentyhq/core-team-issues/issues/1276 

We now need to take fields permissions into account when determining if
a cell is editable or not.

a record field (= a cell) is read only if one of the condition is met:
- the object of the record is read-only (can be determined at table
level) by permission setting
- the field of the object is read-only (can be determined at column
level) - either by permission settings or by system (some workflows
fields for intance)
- the record is deleted (can be determined at row level) 

we reorganized the code to avoid re-computing known information as much
as possible.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-08-04 18:42:27 +02:00
Charles BochetandGitHub 42045667a4 Fix id typing in metadata generated schema (#13596)
In our Graphql schema, ids are typed as UUID.

Our FE codegen is typing it as 'any', unless we say otherwise. Fixing it
and fixing the impacts in the codebase
2025-08-04 18:40:26 +02:00
StephanieJoly4andGitHub 32736ccd95 User guide - Getting around Twenty and 3 steps to get started articles
test new article for User Guide - overview of navigation
2025-08-04 17:31:22 +02:00
martmullandGitHub b12fad533d Fix workflowRun real time updates (#13605)
as title
2025-08-04 15:28:22 +00:00
99f8891f3a i18n - translations (#13606)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-04 17:21:24 +02:00
Charles BochetandGitHub 2eeddcddc6 Add TwentyORM query read timeout exception (#13603)
In this PR:
- adding a try / catch around all ORM internal methods save, insert,
upsert, findOne, ...
- leveraging this error to prevent messageChannels to get FAILED
- optimizing messaging BATCH_SIZE and THROTTLE threshold according to
local tests
- 

<img width="1510" height="851" alt="image"
src="https://github.com/user-attachments/assets/802fd933-caac-4291-9cde-34a1ddf59c06"
/>
2025-08-04 17:16:16 +02:00
Abdul RahmanandGitHub d958447bb6 Update workflow stepId type (#13602) 2025-08-04 16:53:42 +02:00
MarieandGitHub 2cebb72447 [permissions] Return all columns by default for upsert (#13587) 2025-08-04 16:49:56 +02:00
martmullandGitHub 72ffee39a7 Fix seed workspace (#13601)
Add missing positions and nextStepIds to seed workspace
2025-08-04 14:39:52 +00:00
8a2e38da87 i18n - translations (#13600)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-04 16:21:45 +02:00
martmullandGitHub 9a05673093 Implement branch front end (#13489)
First PR to support workflow branches on frontend
2025-08-04 14:11:46 +00:00
Félix MalfaitandGitHub 2c87c6fc1b Add local storage effect to save sidebar state (#13591)
Add local storage effect to keep the behavior across sessions
2025-08-04 14:44:11 +02:00
Félix MalfaitandGitHub 86f813c26d Disable changing label identifier for standard objects (#13593)
Fixes https://github.com/twentyhq/core-team-issues/issues/994
2025-08-04 14:43:56 +02:00
Charles BochetandGitHub ae17640fbc Fix upsert in ORM (#13589)
Before:
<img width="1496" height="850" alt="image"
src="https://github.com/user-attachments/assets/bb334c4d-99c3-4237-90e3-02400ab566f5"
/>

After: 
<img width="1496" height="850" alt="image"
src="https://github.com/user-attachments/assets/4e53bdf0-6f2c-4a11-9836-d83f44291a0b"
/>


Query:
```
mutation CreatePerson($upsert: Boolean, $data: PersonCreateInput) {
  createPerson(upsert: $upsert, data: $data) {
    jobTitle
    id
  }
}
```

Variables:
```
{
  "upsert": true,
  "data": {
    "name": { "firstName": "marie"}
  }
}
```
2025-08-04 14:13:55 +02:00
nitinandGitHub b85918fc7a fix: API key regeneration fails when roles feature is disabled (#13588) 2025-08-04 16:38:51 +05:30
Félix MalfaitandGitHub 5c7c8d1bba Reset overflow visible to previous value, fix console error (#13586)
Fixing two issues I introduced in #13583 and #13573

- Overflow visible is not needed, I missed that as I was switching
between different implementations
- Button within button not allowed (not the prettiest fix but I din't
think it's worth digging deeper)
2025-08-04 13:00:54 +02:00
Félix MalfaitandGitHub 5e418e3667 Add tooltip when navigation menu isnt expanded (#13583)
<img width="130" height="687" alt="Screenshot 2025-08-04 at 09 56 06"
src="https://github.com/user-attachments/assets/2cbc5c46-6952-4041-b6f2-d68e411629de"
/>
2025-08-04 11:46:15 +02:00
Abdul RahmanandGitHub 01f25519f6 fix: standardize GraphQL schema UUID field types (#13550)
Closes [#1264](https://github.com/twentyhq/core-team-issues/issues/1264)
2025-08-04 11:43:48 +02:00
Paul RastoinandGitHub d8ec2e3959 Field metadata v2 relation (#13562)
# Introduction
- deferrable constraint on foreignKey definition
- fix relation creation input transpilation to flat field metadata
- fix validation to allow contextual validation on not already created
field metadata ( usefull for relation, and will be necessary for the
import )
2025-08-04 09:30:13 +00:00
Thomas TrompetteandGitHub 810fe06aa3 Refacto filter action + handle missing composite fields (#13557)
- handle missing composite fields
- refacto filter action to be more reliable

Remaining improvements:
- filter out some field types
- improve relations
2025-08-04 10:19:52 +02:00
MarieandGitHub 8d367f1ec3 [permissions] Remove non-readable field from aggregate options (kanban) (#13559)
Non-readable fields should not be an option for aggregate, as they
currently were still in kanban headers.

<img width="769" height="733" alt="Capture d’écran 2025-08-01 à 18 16
16"
src="https://github.com/user-attachments/assets/475621a6-9a62-4577-8dd4-eb4a3ace36e2"
/>
2025-08-04 07:17:55 +00:00
Charles BochetandGitHub dc3c194f3e Improve messaging sync performances (#13549)
This PR aims to improve performances as we are making A LOT of queries
after having added events emission to the ORM layer. While investigating
issues, I've come across multiple problems I will describe below

## Add index on workspace.activationStatus as we are querying it a lot

As per title

## Add logs on core datasource destroy

It seems that we have postgres connection pool destruction in
production. I cannot reproduce locally but I suspect the Query Timeouts
to be the root cause. I'm fixing most of the Query Timeouts cause in
this PR but I'm adding the logs so we have more information in case in
keeps happening in production.

## GraphQL query runner createMany

It was using a for loop on each record. This is as issue has we will
emit an event separately for each record => we should always try to
batch events.
Replacing by a save on all records. Note that this is not perfect as we
should avoid using save (bad performances), and use insert + updateMany
instead. As I have follow up discussions regarding permissions, I
haven't replaced it by insert and updateMany yet. Using save instead of
a for loop makes the problem less worrying.

## Introduce updateMany in ORM @Weiko @ijreilly FYI

.save(manyRecords) is bad as it's querying the data for no good reason
(and doing a select for each record...).
We already have .insert(), i'm introducing .updateMany()

I think our ORM layer should be simplified a lot but I'm not starting
the refacto yet

## Fixing ORM @Weiko @ijreilly  FYI
- Fixing events emission in delete function
- Fixing events emission in insert function
- make sure everything is batched

## Events performance @Weiko @ijreilly FYI

Do not emit timelineActivity db events as this does not seem useful and
is quite heavy

## Messaging and Calendar performance @bosiraphael FYI

Rework many functions to make sure they are batched. This does not touch
the driver layer and I have heavily tested it. (multiple account, with
multiple channels, common thread, common messages, etc...)

## Workflow Trigger relation Fetch performance @martmull FYI

Improved performance by batching
2025-08-03 23:56:44 +02:00
996a471a4e i18n - translations (#13578)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-03 21:31:35 +02:00
b8a26dfe8c Fix breadcrumbs to display friendly object names instead of API names… (#13573)
Fixes #13250

This PR fixes the breadcrumb display issue where API names were shown
instead of friendly object names when navigating to related objects in
the detail view.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-08-03 21:18:32 +02:00
253a9221db i18n - translations (#13575)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-03 15:39:52 +02:00
db2ef7cc5b Removed Line 52 from SETTINGS_NON_COMPOSITE_FIELD_TYPE_CONFIGS (#13572)
Removed the Variable FeildMetaDataType.UUID at line 52 
from
twenty\packages\twenty-front\src\modules\settings\data-model\constants\SettingsNonCompositeFieldTypeConfigs.ts

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-08-03 13:25:02 +00:00
nitinandGitHub 4cd2a87833 Enable roles on api keys (#13334) 2025-08-02 23:54:10 +02:00
2bda929984 feat: add sub fields for address (#13566)
https://github.com/user-attachments/assets/8fe9079d-9b66-4b42-8b11-ad713e9de666

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-08-02 23:43:39 +02:00
WeikoandGitHub 4624739879 Fix eventEmitter emitting when diff is empty (#13560) 2025-08-01 19:13:26 +02:00
Paul RastoinandGitHub b98d8c4d39 Fix flatFieldMetadata transpiler to fit real cache typing (#13529)
# Introduction
The cache is not accurately typed regarding the `fieldMetadataMaps` they
do not contain relations
In this way we:
- Created dedicated transpilation tools for cache manipulation
- Avoided recursivity in transpilation tools
- Fix and finalized the createMany fields metadata service v2
- Refactor the validator to handle validation :)

## What's next:
- Implem integration tests to make things run 🙃 
- migrate existing settings valdiation
- Finish the create object metadata service
- Handle update input transpilation and validation
2025-08-01 18:39:11 +02:00
Antoine MoreauxandGitHub dd47bfe6d5 feat(database): add chunked insert method for ClickHouse integration (#13534) 2025-08-01 18:38:46 +02:00
e3967484ef i18n - translations (#13556)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-01 17:21:06 +02:00
c3a9843fcb AI settings tab (#13496)
https://github.com/user-attachments/assets/87f5a556-ff12-4ce0-aaa7-9120c0432151

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-08-01 16:59:28 +02:00
nitinandGitHub 75214c3e61 fix: prevent saving tiny scroll positions in restoration hook (#13554)
fixes 1-2px scroll restoration issue

- browser reports 1-2px instead of exact 0 when at top
- old logic kept saving these tiny values 
- now clears storage when <= 3px (essentially at top)
- prevents weird micro-scroll when returning to pages


re: [greptile infinite polling
concern](https://github.com/twentyhq/twenty/pull/13363#discussion_r2247232974)
- not valid in practice:
- restoration only runs if position was previously saved
- no scroll = no save = no restore = no polling
- tested across all page types, zero infinite loops

tested: works perfectly, no side effects
2025-08-01 20:21:52 +05:30
c879136d29 i18n - translations (#13555)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-01 16:49:39 +02:00
a5cb3168c1 feat: merge records button in RecordDetailDuplicatesSection (#13537)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-08-01 16:37:20 +02:00
c44f610872 [POC] multi select drag and drop on record board (#13053)
closes https://github.com/twentyhq/twenty/issues/13036

Inspiration:
https://github.com/hello-pangea/dnd/blob/main/docs/patterns/multi-drag.md

Question: Should we have it for tables too? :)


https://github.com/user-attachments/assets/64a3c4c5-40bc-4ca4-b296-685027d08861

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-08-01 14:59:35 +02:00
73f12d3504 [admin-panel] - add scroll restoration and filter persistence on config variables (#13363)
addressing
https://github.com/twentyhq/twenty/issues/13323#issuecomment-3101630375

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-08-01 09:48:36 +02:00
ddfc68378c i18n - translations (#13547)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-01 09:22:07 +02:00
Antoine MoreauxandGitHub 23353e31e6 feat(domain-manager): refactor custom domain validation and improve c… (#13388) 2025-08-01 09:01:27 +02:00
51340f2b0e enhance globalComponentInstanceContextMap type safety (#13544)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-08-01 08:51:25 +02:00
aa84952117 i18n - translations (#13546)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-08-01 07:52:21 +02:00
neo773andGitHub 9c972ece1b fix: delete account (#13543)
/closes #13540
2025-08-01 07:45:48 +02:00
MarieandGitHub b41502a4b8 [permissions] Update permission check layer (#13485)
Fixes https://github.com/twentyhq/core-team-issues/issues/1262

In this PR we add the update permission check layer by 
- for the graphql api: extracting columns to update from the
expressionMap
- for rest api: .save() is used so we need to add the permission layer
to .save directly. We also take advantage of this PR to filter out
non-readable fields from save response (other save returns the whole
entity) - this was planned in
https://github.com/twentyhq/core-team-issues/issues/1216

The current solution does not work with rest api depth 2 queries, but
this seem to already not work on main (for timeout reasons though, so
different). I offer to create a ticket to fix it altogether later.
2025-07-31 18:37:01 +02:00
3e9b642f7f i18n - translations (#13531)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-31 15:45:04 +02:00
Thomas TrompetteandGitHub 664fd9fabd Do not enrich relations when id undefined (#13530)
Fixes https://github.com/twentyhq/twenty/issues/13428
We perform the call enrichment even with id undefined. It returns the
first item in DB.

Adding two more fixes related to filters:
- Conditions title
- Fixing placeholder color for select control (only other impacted field
is in Advanced filters)
2025-07-31 13:40:41 +00:00
42c15b11f8 i18n - translations (#13528)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-31 15:04:09 +02:00
Charles BochetandGitHub c166cff315 Fix linter performance front (#13527) 2025-07-31 15:03:32 +02:00
Paul RastoinandGitHub 14537d74b4 FlatFieldMetadataType hashmap arch and enum validation (#13502)
# Introduction
- FlatFieldMetadataType validators hashmap
- Do not fail fast on validation but aggregate errors
- Implemented `enum` validation
- Plugged the new v2 dynamic call in the field metadata service v2

## What's next:
- Implem integration tests to make things run 🙃 
- migrate existing settings valdiation
- Finish the create object metadata service
- Handle update input transpilation and validation

## Open question
Should we implement, not covered validation ?, adding strictness now or
never.
This will be required by the import anw

## Discovered issue with cache
Currently the cache is not accurately typed, `fieldsById` map are not
storing any relations.
Which means the current transpilation tools are hitting undefined at
runtime
In the best of the world we will refactor the cache to be storing
`FlatObjectMetadata` and `FlatFieldMetadata` so we don't even have to
transpile them for validation and so on
But it would require to refactor the loaders that returns the cache to
the front on hit as FieldMetadataEntity, so we might land on a lighter
solution to rather add a new `getExistingFlatCache` that handles the
transpilation itself
About to do that in an other PR to be discussed with Coco
2025-07-31 14:54:39 +02:00
Paul RastoinandGitHub 7e7c64ac35 test(front): coverage limit (#13526)
Coverage test front check fails on main, for some reason
2025-07-31 14:15:38 +02:00
Félix MalfaitandGitHub f52973d71d Fix 2fa auth and token format migration (#13523)
Fix the 2FA setup and also make some changes so that the transition
towards a new token format introduced in a previous PR happens more
smoothly
2025-07-31 14:13:12 +02:00
c8128c4d3f i18n - translations (#13521)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-31 12:21:16 +02:00
06e0814ce8 feat: merge records (#13436)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-07-31 10:06:36 +00:00
Antoine MoreauxGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix MalfaitFélix Malfait
00d12e854a BREAKING - feat(auth): refactor tokens logic & enhance email verification flow (#13487)
- Replaced `getAuthTokensFromLoginToken` with
`getAccessTokensFromLoginToken` for clarity.
- Introduced `getWorkspaceAgnosticTokenFromEmailVerificationToken`.
- Extended mutation inputs to include `locale` and
`verifyEmailNextPath`.
- Added email verification check and sending to various handlers.
- Updated GraphQL types and hooks to reflect these changes.


Fix #13412

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-31 12:00:59 +02:00
Félix MalfaitandGitHub 463e2e89c8 Remove mistakenly added files (#13514)
As per title
2025-07-31 09:41:43 +02:00
neo773andGitHub 66c484fe11 fix: add userFriendlyMessage to handleDuplicateKeyError (#13513)
/closes #13512
2025-07-31 09:02:08 +02:00
WeikoandGitHub 689a346c2e Implement Workspace Schema Manager Service (#13501)
This PR adds a new set of services that can be used to manage a DB
schema (workspace schema in this case) such as creating tables, columns,
enums, indexes, FK, etc... Nothing should be new as I've simply
reimplemented what we can already do in the current workspace migration
runner but this using raw queries for everything as we faced some
performances issues in the past using the orm API directly. Some methods
are new but were picked from usages in migration commands so I took the
liberty to implement them as well in case they are still needed.
This is isolated enough to be used in a command but the first use case
will be to use it in the new WorkspaceSchemaMigrationRunnerService that
will call those methods from the migration instructions
2025-07-30 19:24:39 +02:00
Abdul RahmanandGitHub da79afa80a AI Agent handoffs (#13472) 2025-07-30 16:56:58 +02:00
b0c1404d23 i18n - translations (#13503)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-30 15:28:21 +02:00
Thomas TrompetteandGitHub d4011edbbf Add design for selected filter (#13498)
On select, filter design should be updated as it is for other nodes

<img width="106" height="70" alt="Capture d’écran 2025-07-30 à 12 12
09"
src="https://github.com/user-attachments/assets/66aa7838-2fb3-4593-af32-a9b361eb3225"
/>
<img width="106" height="70" alt="Capture d’écran 2025-07-30 à 12 12
25"
src="https://github.com/user-attachments/assets/5627427b-4c36-4592-b5bb-e5d87d59232d"
/>
2025-07-30 15:24:01 +02:00
Paul RastoinandGitHub 29a4f4d685 CreateFieldInput transpilation to FlatFieldMetadata, FlatFieldMetadata validation (#13493)
# Introduction
Following https://github.com/twentyhq/twenty/pull/13420

What has been done:
- `CreateFieldInput` transpilation to `FlatFieldMetadata`
- `FlatFieldMetadata` validator service
- A lof of transpilation utils from `input` to `flatObject` or
`flatField`
- Created dedicated v2 api metadata services
- Introducing `inferDeletionFromMissingObjectFieldIndex` in the builder,
to avoid diffing every object and field of the current workspace we
allow only generating create/update migration operations, usefull when
passing by the api metadata


## We still need to in another PR:
- Implement a strong unit test coverage and critical functions and
services
- Finalize flat field metadata validation exception for `options`
`defaultValue` `settings` and `relations`
- Finalize `flatObjectMetadata` validation and v2 service refactor
- Plug the new service when feature flag is enabled
2025-07-30 15:08:11 +02:00
neo773andGitHub 0e4e3acaba fix: IMAP Import (#13500)
/closes #13397
2025-07-30 15:08:00 +02:00
11a0fce1c8 i18n - translations (#13499)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-30 13:01:03 +02:00
ad69ed9aba feat: allow users to start the calendar week on Monday (#13295)
resolve twentyhq/core-team-issues#1255
- Introduced a new field isWeekStartMonday in the workspaceMember table.

- Added a function updateCalendarStartDay to update the
isWeekStartMonday value when the user toggles the corresponding field in
the settings.

The logic works for me, but I couldn’t find a way to create the column
locally in the database for the workspaceMember tables. Please let me
know if this approach looks good and how to properly create dynamic
columns that are not directly handled via migration.


https://github.com/user-attachments/assets/4eebada5-6a96-4a88-8e96-98f1501859e3

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-30 12:46:05 +02:00
1972e2fbf7 i18n - translations (#13495)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-30 11:22:26 +02:00
Nabhag MotivarasandGitHub 316f2ec38c refactor: to useCopyToClipboard to catch errors - when user has disable copy clipboard permission in browser (#13330)
as discussed here
https://github.com/twentyhq/twenty/issues/13292#issuecomment-3092215050
with @prastoin

- [x] introduce optional message param to `copyToClipboard` method in
`useCopyToClipboard` and refactor it across app, as in case if user has
disallowed clipboard permission in BROWSER unprotected clipboard access
breaks without catch.

- [x] Email copied to clipboard

- [x] run lingui extract
2025-07-30 11:13:55 +02:00
00f0c68478 fix: Display year for releases from previous years on website (#13276) (#13291)
### 🐛 Bug Fix

**Fixes #13276 - Website does not show year of releases**

### 📝 Description

Fixed the Twenty website to properly display release years for previous
year releases and standardized date formatting.

**Key Changes:**
- Show year for releases from previous years
- Abbreviate month names for consistent layout (e.g., "April" → "Apr")
- Added fallback to prevent runtime errors when no releases exist

### 🔧 Files Changed

- **`formatDisplayDate.ts` (new)** - Utility function for consistent
date formatting
- **`Release.tsx`** - Use utility function and improve CSS layout
- **`page.tsx`** - Add fallback for undefined `latestGithubRelease`

### 🧪 Example Output

| Before | After |
|--------|-------|
| `April 25th 2024` (missing year) | `Apr 25th 2024` |
| `April 25th 2025` | `Apr 25th` |
| Runtime error | Graceful fallback |

### � Screenshots

**Before & After:**
<img width="1055" height="778" alt="image"
src="https://github.com/user-attachments/assets/68f227ec-2b1f-486b-89a6-8c3d8058ba36"
/>

<img width="1055" height="778" alt="image"
src="https://github.com/user-attachments/assets/74ed84b3-3a65-4090-b371-a48c25740bbd"
/>


---

**Related Issue:** Closes #13276

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-29 18:58:49 +02:00
Paul RastoinandGitHub c1bf0a1fbf Object metadata API create one using workspace migration v2 (#13420)
# Introduction
In this PR we create basic transpilation methods and utils to handle
input to flat, entity to flat, object maps to flat. In order to
transpile everything into a common validation that will be implemented
in another PR

## FieldMetadataEntity typing
Added `never | null` to fields that should never be in order to ease
general abstracted method to pass null, as anw it's what is in the
database

## Todo
- ~~Create a feature flag~~
- Integration test for object creation through metadata api + pg col
introspection and snapshoting
2025-07-29 17:47:28 +02:00
Thomas TrompetteandGitHub 600df4fd90 Reset relation id to null rather than empty string (#13488)
Empty string rases an error "invalid uuid".
When resetting a relation field - no value or deleting variable - we
should set null rather than an empty string. Otherwise the user that set
a relation field once in a workflow step has to always keep a value set.
2025-07-29 17:38:10 +02:00
Antoine MoreauxandGitHub 40f529f1ac feat(ai): add markdown in ai chat (#13402) 2025-07-29 15:13:00 +00:00
Thomas TrompetteandGitHub cbf731dba7 Filter batch fixes (#13486)
- handle multiselect and select

Before
<img width="200" height="200" alt="Capture d’écran 2025-07-29 à 13 47
36"
src="https://github.com/user-attachments/assets/02fd2085-f2a5-405e-adb4-a53457b43d95"
/>

After
<img width="200" height="200" alt="Capture d’écran 2025-07-29 à 13 44
09"
src="https://github.com/user-attachments/assets/b85dde54-0284-4f4f-b19d-b86516afdf81"
/>

- Fix node display in run

Before
<img width="200" height="200" alt="Capture d’écran 2025-07-29 à 13 47
13"
src="https://github.com/user-attachments/assets/c32dedaf-0c37-4300-9693-27a790a4d727"
/>

After
<img width="200" height="200" alt="Capture d’écran 2025-07-29 à 13 44
58"
src="https://github.com/user-attachments/assets/ab4449d0-933d-49f4-8572-75e484401c2c"
/>

- Remove assert to fix discard draft
- handle label for readonly
2025-07-29 16:19:22 +02:00
Lucas BordeauandGitHub d61eb1a951 Remove all legacy state management (#13476)
This PR removes every legacy state management logic left in the code
base, we only keep our last component state management logic.

Removed : 
- Scoped states logic
- Dropdown scope logic
- Scope id naming
- Component state v1
- Component state v2_alpha


# QA

| Component | Comments |
| --- | --- |
| AttachementDropdown | Ok |
| ObjectTasks | Ok |
| ActivityRichTextEditor | Ok |
| App | Ok dialogs work |
| AppRouterProviders | Ok dialogs work |
| RecordBoardScrollToFocusedCardEffect | Ok |
| RecordBoard | Ok |
| RecordBoardCard | OK |
| useSelectAllCards | Ok |
| RecordInlineCell | Ok |
| useInlineCell | Ok |
| RecordDetailRelationRecordsListItem | Ok |
| RecordDetailRelationSectionDropdownToMany | Ok |
| RecordDetailRelationSectionDropdownToOne | Ok |
| useHandleContainerMouseEnter | Ok |
| useResetTableRowSelection | Ok |
| useSelectAllRows | Ok |
| useSetRecordTableData | Ok |
| useRecordTable | Ok |
| useRecordTableMoveFocusedCell | Ok |
| useRecordTableMoveFocusedRow | Ok |
| useMoveHoverToCurrentCell | OK |
| useTriggerActionMenuDropdown | Ok |
| RecordTableBodyDragDropContextProvider | Ok |
| RecordTableHeaderCell | Ok |
| useSetCurrentRowSelected | Ok |
| useRecordTitleCell | Ok |
| SettingsObjectFieldActiveActionDropdown | Ok |
| SettingsObjectFieldInactiveActionDropdown | Ok |
| SettingsObjectFieldItemTableRow | Ok |
| SettingsObjectInactiveMenuDropDown | Ok |
| SettingsRoleEditEffect | Ok |
| SettingsRolesQueryEffect | Ok |
| Dropdown | Ok |
| useSelectableList | Ok |
| useSelectableListHotKeys | Ok |
| useSelectableListListenToEnterHotkeyOnItem | Ok |
| useNavigationSection | Ok |
| useCreateViewFromCurrentState | Ok |
| useDeleteViewFromCurrentState | Ok |
| useUpdateViewFromCurrentState | Ok |
| ViewPickerFavoriteFoldersDropdown | Ok |
| useCreateViewFromCurrentView | Ok |
| ViewBarDetails | Ok |
| WorkflowRunVisualizer | Ok |
| useHandleWorkflowRunDiagramCanvasInit | Ok |
| WorkflowDiagramCanvasBase | Ok |
| WorkflowRunVisualizerEffect | Ok |
| useRemoveStepFilter | Ok |
| useRemoveStepFilterGroup | Ok |
| useUpsertStepFilterSettings | Ok |
| WorkflowFindRecordsFilters | Ok |
| SettingsObjects | Ok |
2025-07-29 09:52:24 +00:00
Vicky WangandGitHub bf8beb5735 Permissions V1 Documentation (#13473)
## PR Summary
- Add new setting page to Twenty user-guide
- Added V1 Permissions documentation + cover
2025-07-29 11:15:00 +02:00
Félix MalfaitandGitHub 7f67fc8257 Fix Website deploy (#13482)
Fix broken website deploy due to absolute path
2025-07-29 11:03:10 +02:00
a47a5683fd i18n - translations (#13483)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-29 10:51:55 +02:00
Thomas TrompetteandGitHub 8513d14157 Filter action fixes on select field (#13477)
<img width="475" height="322" alt="Capture d’écran 2025-07-28 à 18 45
51"
src="https://github.com/user-attachments/assets/922201d0-0a80-4ceb-848f-9a391e3337a4"
/>

<img width="491" height="72" alt="Capture d’écran 2025-07-28 à 18 46
11"
src="https://github.com/user-attachments/assets/9d6674ad-9b8c-422a-a6ac-5ec91deac62b"
/>
2025-07-29 10:46:34 +02:00
Balaji KrishnamurthyandGitHub ca3e315e0c move APIs and Webhooks section out of advanced mode (#13481)
Closes #13468

The `isAdvanced` parameter for `Developers`, `APIs` and `Webhooks` were
set to `true` previously. Now they are set to `false`. The `Functions`
section still appears under `Advanced Mode` as the issue did not specify
whether it had to be moved as well.

Attaching a loom recording of before and after for verification:

[Before](https://www.loom.com/share/a06f7aea758649cc952db617074d1361?sid=8564da09-e44b-4b64-8dab-ea3f9adf7423)

[After](https://www.loom.com/share/b631397d5f7d476293e6771f6804e965?sid=f7154952-ea6b-4561-8532-5794b8960cd4)
2025-07-29 10:00:06 +02:00
4eba13e9fb feat: add Google Place Autocomplete for address fields (#13450)
resolve #13253
This PR enables the use of Google Place Autocomplete and Place Details
APIs in the backend. It allows users to automatically fill in address
fields by typing into the address1 input. The input is debounced, then
the Autocomplete API is called. Once the user selects an address, the
Place Details API is used to parse and fill in the individual address
fields.


https://github.com/user-attachments/assets/e04b8474-25b8-48f5-83d0-2074f8d5fc94

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-29 09:56:08 +02:00
EtienneandGitHub c186b78f67 Connect/Disconnect in .save (#13444) 2025-07-28 20:28:41 +02:00
EtienneandGitHub 2a82a33fff remove gql connect input for morph field - temporary (#13475)
related to https://github.com/twentyhq/core-team-issues/issues/1278
2025-07-28 18:43:27 +02:00
MarieandGitHub 16ba72edab [permissions] Adapt FE to non-readable fields (#13440)
Fixes https://github.com/twentyhq/core-team-issues/issues/1261 and
https://github.com/twentyhq/core-team-issues/issues/1153

In this PR we
- remove fields user do not have read access on from queries (findMany,
findDuplicates, returned fields from create or update etc.)
- remove fields user do not have read access on from views 

This is behind a feature flag
2025-07-28 16:24:08 +00:00
Raphaël BosiandGitHub 4131be2a68 Improve core view migration (#13474)
- Improve migration script to make it idempotent
- Fix update on view and view filters (`displayValue` exists on
workspace view filter but not on core view filter,
`kanbanFieldMetadataId` exists on workspace view but not on core view)
2025-07-28 15:52:57 +00:00
GuillimandGitHub 9c82121b87 fixing issue with QueryFailed on message import (#13471)
Failure was due to a deletion of a workspace while a cron job "message
import" had already started
2025-07-28 17:05:36 +02:00
34d126f727 add command to destroy workspaces (#13447)
Dev tool to enable workspace destroy - two guards added (destroy only
billing inactive workspace + soft deleted)

closes : https://github.com/twentyhq/core-team-issues/issues/1238

---------

Co-authored-by: Guillim <guillim@users.noreply.github.com>
2025-07-28 16:51:02 +02:00
Lucas BordeauandGitHub a818a70e40 Cleanup remaining old component states (#13435)
This PR cleans up the remaining legacy component states.

Everything that is on the v1 of component states, scoped states,
dropdown scope, scoped id, etc.
2025-07-28 14:35:36 +00:00
EtienneandGitHub 569e1e03af Cleaning command - add log (#13464) 2025-07-28 14:53:19 +02:00
Raphaël BosiandGitHub 7cf778b579 Synchronization between Core Views and Workspace Views (#13461)
Closes https://github.com/twentyhq/core-team-issues/issues/1248

- Create listeners on each CRUD operation for all view related objects
and update the core views accordingly

Some fields have to be parsed since we changed the data model a little
bit when switching to core views.
2025-07-28 14:41:27 +02:00
GuillimandGitHub 400dd6d969 bug fix (#13466)
We should not enqueue jobs "unmatch participants" with empty email.

This was done because of deleting persons while persons may have empty
emails

Fixes https://github.com/twentyhq/twenty/issues/13462
2025-07-28 13:56:20 +02:00
Raphaël BosiandGitHub ae47157818 Fix empty emails critical bug (#13465)
Fixes https://github.com/twentyhq/twenty/issues/13398

This bug was introduced by https://github.com/twentyhq/twenty/pull/13215

The emails were empty in scenarios where the user wasn't authenticated
(reset passwords for instance) because in `hydrateGraphqlRequest` the
information about the locale was added only if the user was
authenticated `!this.isTokenPresent(request)`. So the locale was
undefined making ` i18n.activate(undefined) ` fail silently resulting in
an empty email.
2025-07-28 12:56:29 +02:00
martmullandGitHub c59eb20886 Fix metadata playground not accessible (#13446)
as title


## Issue
<img width="982" height="487" alt="image"
src="https://github.com/user-attachments/assets/536567a3-ec36-45ed-b928-5ba4fd98ea70"
/>
2025-07-25 17:26:29 +02:00
GuillimandGitHub 8ea816b7ef morph relation : renaming an object (#13404)
# Why
If we have a Morph Relation, like :
Opportunity <-> Company & People

Let's say it's a MANY_TO_ONE on Opportunity side

Then we have two joinColumnNames looking like
- ownerPersonId
- ownerCompanyId

Let's say someone renames the obejct Person (assume we can even though
standard obejcts cannot be renames per say at the moment in the API)

We need to update the joinColumnName and create the associated
migrations
2025-07-25 16:40:51 +02:00
martmullandGitHub 9380a1386a Fix missing components.schema for webhooks (#13433)
Webhooks are still documented in core playground to detail Webhooks of
core objects.
We moved webhooks to metadata playground and forgot to keep computation
of WebhookForResponse

This PR adds it back
2025-07-25 16:36:11 +02:00
WeikoandGitHub d1b11bafe6 remove search any field feature flag (#13442)
<img width="1189" height="368" alt="Screenshot 2025-07-25 at 15 18 39"
src="https://github.com/user-attachments/assets/22879517-60bc-4884-8386-35a0b06a6636"
/>
2025-07-25 15:32:24 +02:00
WeikoandGitHub 523d0ac17c Revert "Added public lab feature flag for search any field" (#13441)
Reverts twentyhq/twenty#13430

We will release this in the 1.2
2025-07-25 15:10:58 +02:00
EtienneandGitHub 13bed8e4d2 fix createMany resolver when updating softdeleted record (#13425)
Context: updateOne/Many works on soft deleted records but the update of
the upsertMany throws error

fixes https://github.com/twentyhq/twenty/issues/13195
2025-07-25 14:35:04 +02:00
EtienneandGitHub e386303fd3 Disconnect - fix disconnect false (#13439)
Context: {disconnect: false} disconnects relation > fix in this PR + add
integration test
2025-07-25 14:26:05 +02:00
Thomas des FrancsandGitHub fecac68760 1.2 changelog (#13438) 2025-07-25 14:24:50 +02:00
ab054d51f2 i18n - translations (#13437)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-25 13:33:08 +02:00
d4ca63dbb7 Update Connected Accounts Design (#13332)
/closes #13328

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-25 13:18:02 +02:00
martmullandGitHub 79992b53d1 Fix insert step button not displayed (#13432)
as title
2025-07-25 09:35:48 +00:00
Lucas BordeauandGitHub d767a1ca47 Added public lab feature flag for search any field (#13430)
This PR adds a public feature flag for search any field.

This feature flag default value has been set to false also to avoid
breaking the frontend, we'll wait for a sync metadata in the next
release on all workspace to remove this feature flag.
2025-07-25 09:26:53 +00:00
Thomas TrompetteandGitHub ae13d08017 Improve auth google error msg (#13431)
As title
2025-07-25 11:14:27 +02:00
Thomas TrompetteandGitHub 041d55b605 Fix to gmail / ms auth (#13429)
Use user principal for MS + add verif true for google
2025-07-25 11:10:38 +02:00
3fc795f450 i18n - translations (#13426)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-25 10:01:20 +02:00
EtienneandGitHub 741924751b Connect - Import Relation (#13419)
re-opened https://github.com/twentyhq/twenty/pull/13213
2025-07-25 09:48:17 +02:00
ca27995ca6 i18n - translations (#13424)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-25 08:22:14 +02:00
4b95de6775 Add Import CSV and Export CSV Permissions (#13421)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-25 08:07:38 +02:00
Thomas TrompetteandGitHub f411bd1b0e Add upgrade enqueue enum V2 command (#13422)
Duplicated the existing command `AddEnqueuedStatusToWorkflowRunCommand`.
Adding two steps:
- fetch the `workflowRun` object of the selected workspace
- using that object metadata id in the status field selection
2025-07-24 19:14:03 +02:00
Thomas TrompetteandGitHub 191d3531bf Manage composite fields in step filters (#13407)
- add to step output schema the information that field is a composite
sub field
- from output schema, when selecting the variable, copy all info
required to stepFilter
- from stepFilter, when selecting a value, display a special component
for composites
2025-07-24 17:50:07 +02:00
WeikoandGitHub 3aba04abcd Fix date field creation with disabled save button (#13416)
Fixes https://github.com/twentyhq/twenty/issues/13297

See SettingsDataModelFieldDateForm form validation which expects a
settings field to be present with a default display format. This PR adds
the missing initial value.
2025-07-24 17:19:40 +02:00
EtienneandGitHub 88a6913217 Connect/Disconnect - Add Disconnect logic + Migration to query builders (insert/update) (#13271)
Context : 
Large PR with 600+ test files. Enable connect and disconnect logic in
createMany (upsert true) / updateOne / updateMany resolvers

- Add disconnect logic
- Gather disconnect and connect logic -> called relation nested queries
- Move logic to query builder (insert and update one) with a preparation
step in .set/.values and an execution step in .execute
- Add integration tests

Test : 
- Test API call on updateMany, updateOne, createMany (upsert:true) with
connect/disconnect
2025-07-24 17:04:38 +02:00
Paul RastoinandGitHub 7bfa003682 Workspace migration v2 Metadadata runner object and field (#13377)
# Introduction
Created the runner metadata for the field and object
We should keep in mind that any runner handler will only iterate over an
atomic instance of entity ( object field index etc )
Never triggerring any side effect or whats over

In this way we will need to implement a deferred transaction, as for
when we create a relation we will inject to the first created field of
both the `relationTargetFieldMetadataId` deterministically computed
before its own creation
This would result in pg constraint brokage if not deferred

## Updates
- We decided gather create_fields under the create_object as they will
be building within the same sql query. This will ease both generation
and computation and avoid disassembling to reassemble afterwards
- Refactored FlatFieldMetadata to handle relation typing with flat
occurences
```ts
  runCreateFieldSchemaMigration = async ({
    action,
    queryRunner,
  }: WorkspaceMigrationActionRunnerArgs<CreateFieldAction>) => {
    if (isFlatFieldMetadataEntityOfType(action.flatFieldMetadata, FieldMetadataType.RELATION)) {
      action.flatFieldMetadata.flatRelationTargetObjectMetadata
    }else {
      action.flatFieldMetadata.flatRelationTargetObjectMetadata // tsc-error never
    }
    return;
  };
```

## TODO
- ~~Discuss action signature with @Weiko in order to anticipate `schema`
runner needed grain~~
- ~~Refactor the object actions to contain picked `flatObjectMetadata`~~
- Implem index service
2025-07-24 17:04:01 +02:00
martmullandGitHub 099694411c Add nextStepIds to trigger (#13413)
We will have floating steps in our workflow with the branch design.
Currently, a step without parent is considered linked to the trigger. We
need to distinguish the 2 cases. Thus this PR:
- add `nextStepIds` to workflowVersion.trigger
- create a command to migrate existing triggers
2025-07-24 16:31:10 +02:00
WeikoandGitHub 7ee250efe7 Fix rest filter parsing (#13414)
Should now properly match logical expressions like and(...), or(...)
instead of and/or without parenthesis, this should fix the issue with
fields that start with or/and
2025-07-24 16:06:06 +02:00
EtienneandGitHub 5c15a5954b Workspace Folder Deletion Error - add logs for investigation (#13385)
https://twenty-v7.sentry.io/issues/6565008010/events/latest/?environment=prod&project=4507072499810304&referrer=latest-event&sort=date

related to https://github.com/twentyhq/twenty/issues/12299
2025-07-24 13:34:41 +00:00
Félix MalfaitandGitHub 16fcaacbdb Translation cleanup (#13411)
Remove dead translations
2025-07-24 15:33:24 +02:00
Félix MalfaitandGitHub ca1e79b9a7 Small translation fix (#13410) 2025-07-24 15:10:15 +02:00
Félix MalfaitandGitHub a83825f4be Remove dead translations (#13409)
Add --clean flag to translation extraction to remove old translations
automatically
2025-07-24 14:50:57 +02:00
e84e47dd6b i18n - translations (#13408)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-24 14:43:28 +02:00
GuillimandGitHub 1ea451c8be Morph Relations : deleteOneField (#13349)
This PR adapts teh deleteOneField to make sure morph relations can be
deleted, either
- from a relation type, 
- or from a morph relation type (which is the most obvious case).

This PR covers 
- the deletion of fieldMetadata 
- and the migrationof workspace schemas, by using the already existing
definition of relation migrations

This PR implements a new test suite: "Delete Object metadata with morph
relation" and completes the other test suites for FieldMetadata and
ObjectMetadata creation/deletion.

Last, we added a nitpick from @paul I forgot on a previous PR on
process-nested-realtion-v2

Fixes https://github.com/twentyhq/core-team-issues/issues/1197
2025-07-24 12:40:14 +00:00
15e13b4267 i18n - translations (#13406)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-24 12:38:12 +02:00
e93adde4b8 Decouple Send Email node from workflows (#13322)
- Renamed `WorkflowActionAdapter` to `ToolExecutorWorkflowAction`
- Renamed `settingPermission` table to `permissionFlag` and `setting`
column to `flag`
- Decoupled the send email logic from workflows to tools
- Add new `Tools Permission` section in FE

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-24 12:31:33 +02:00
eb404478c3 i18n - translations (#13405)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-24 12:21:17 +02:00
Lucas BordeauandGitHub d468c3dc84 Add ability to save any field filter to view (#13401)
This PR adds the ability to save an any field filter to a view.

It adds a new `anyFieldFilterValue` on both core view and workspace view
entities.

It also introduces the necessary utils that mimic the logic that manages
the save of record filters and record sorts on views.
2025-07-24 10:08:16 +00:00
Raphaël BosiandGitHub 7653be8fde Improve view migration command (#13403)
Remove unused imports.
Improve typing.
2025-07-24 11:50:25 +02:00
Paul RastoinandGitHub e18005f937 Fix field metadata comparator (#13390) 2025-07-24 08:22:17 +00:00
9211113a12 Fix AI agent workflow node output variables issue (#13396)
https://github.com/user-attachments/assets/2d086fb6-7c3d-4584-adc0-b2781072be4a

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-07-23 23:08:17 +02:00
23a1540b0f i18n - translations (#13395)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-23 22:21:14 +02:00
Abdul RahmanandGitHub 30dd457313 App version mismatch handling between frontend and backend (#13368)
https://github.com/user-attachments/assets/d153f177-4d70-4ec6-8693-15413e550938
2025-07-24 01:37:02 +05:30
WeikoandGitHub ed36b19af7 Fix increment/decrement methods in twenty orm (#13389)
Increment/Decrement methods were broken and were executing a SELECT
query while selecting twice the same table so the id column reference
was not precise enough. For some reason it didn't recognise the builder
as an update builder AND aliases were not parsed properly
I've modified the code to re-use the existing update method that is
correctly implemented-

BEFORE
```sql
query failed: SELECT entity FROM "workspace_1wgvd1injqtife6y4rvfbu3h5"."viewField" "entity", "workspace_1wgvd1injqtife6y4rvfbu3h5"."viewField" "workspace_1wgvd1injqtife6y4rvfbu3h5.viewField" WHERE "id" IN ($1) -- PARAMETERS: ["cd665f5b-c3ce-44ec-a9b0-51a2d711287e"]
error: error: column reference "id" is ambiguous
```


AFTER
```sql
query: UPDATE "workspace_1wgvd1injqtife6y4rvfbu3h5"."viewField" SET "position" = "position" + 1, "updatedAt" = CURRENT_TIMESTAMP WHERE "id" IN ($1) -- PARAMETERS: ["cd665f5b-c3ce-44ec-a9b0-51a2d711287e"]
```
2025-07-23 19:28:23 +02:00
neo773andGitHub c769f9f2d2 fix: invalid byte sequence for encoding (#13387)
/closes #13366

cc
@FelixMalfait
2025-07-23 18:15:08 +02:00
f439a6cd9e fix: normalize version number using semver.coerce in admin panel version info (#13348)
### Summary

This PR fixes an inconsistency in the display of application versions in
the Admin Panel. Previously, the "Current version" was displayed with a
"v" prefix (e.g., `v1.1.1`), while the "Latest version" was displayed
without it (e.g., `1.1.1`).

### Problem

The inconsistency originated from two different data sources being
handled differently in the backend:
- `currentVersion` was read directly from the `APP_VERSION`
configuration variable, which includes the "v" prefix.
- `latestVersion` was fetched from the Docker Hub API, and the
`semver.coerce()` function was used to parse it, which strips the "v"
prefix.

![Jb ScreenShot 2025-07-22 at 16 47
05@2x](https://github.com/user-attachments/assets/b6243d03-2730-4958-8ad9-68f7e461bbe2)


### Solution

The fix addresses the root cause in the [AdminPanelService] on the
backend. The `semver.coerce()` function is now also applied to the
`currentVersion`.

This ensures that both version numbers are normalized at the data
source, providing a consistent format before being sent to the frontend.
This is a cleaner approach than manipulating the data on the client
side.

**Before:**
- Current version: `v1.1.1`
- Latest version: `1.1.1`

**After:**
- Current version: `1.1.1`
- Latest version: `1.1.1`

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-07-23 15:44:09 +00:00
MarieandGitHub ae6adb3a63 [permissions] Add read field permission check layer (part 1) (#13376)
In this PR, behind a feature flag, we add a permission layer check based
on the read permission.
It is done by computing a map of an object's fields, where keys are the
column names and values the fieldMetadata id, making them comparable to
the restricted fields ids list stored in the permission cache.

For mutations (create, update, delete, destroy), we need to check the
read permission on the returned field, as they may differ from the
updated field. The write field permission will be tackled in a different
PR.
2025-07-23 15:25:34 +00:00
1e5d2f9b21 fix: phone input validation error should display red borders like email input (#13275)
ISSUE 

- closes #13032

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-23 15:52:41 +02:00
186891883e i18n - translations (#13384)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-23 15:27:36 +02:00
nitinandGitHub 0e561e4ef4 fix: migrate webhook and API key REST endpoints to core schema (#13318)
## Problem
After migrating webhooks and API keys from workspace to core level, REST
API endpoints were still creating entities in workspace schema
(`workspace_*`) instead of core schema, causing webhooks to not fire.

## Solution
- Added dedicated REST controllers for webhooks (`/rest/webhooks`) and
API keys (`/rest/apiKeys`)
- Updated dynamic controller to block workspace-gated entities from
being processed
- Fixed OpenAPI documentation to exclude these endpoints from playground
- Ensured return formats match GraphQL resolvers exactly

## Testing
 All endpoints tested with provided auth token - webhooks and API keys
now correctly stored in `core` schema
2025-07-23 13:11:53 +00:00
05a09d7a73 i18n - translations (#13380)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-23 15:04:35 +02:00
Raphaël BosiandGitHub abc3969b41 Create view migration script (#13356)
Create view migration command to copy views from the workspace schema to
the core schema.
Closes https://github.com/twentyhq/core-team-issues/issues/1247
2025-07-23 12:57:16 +00:00
Baptiste DevessierandGitHub 6d3643bb4a Open created filter in command menu (#13379)
https://github.com/user-attachments/assets/d9fc9b9c-8632-4432-b0a4-899662476f09

Closes https://github.com/twentyhq/core-team-issues/issues/1225
2025-07-23 14:52:59 +02:00
Lucas BordeauandGitHub e34ac2967c Add any field filter requests (#13336)
This PR adds any field filter request generation utils with its unit
test.

It also calls this new util in the relevant requests for table and
board.

This PR also adds a new corresponding state in context store so that the
filter is handled in command menu and actions.

We also add this new filter to the aggregate queries.

The RecordShowPage story was also fixed.
2025-07-23 14:50:03 +02:00
oliverGitHubCharles Bochetgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>github-actionsJean-Baptiste RonssinLucas BordeauFélix MalfaitFélix Malfait
4d3124f840 Implement Two-Factor Authentication (2FA) (#13141)
Implementation is very simple

Established authentication dynamic is intercepted at
getAuthTokensFromLoginToken. If 2FA is required, a pattern similar to
EmailVerification is executed. That is, getAuthTokensFromLoginToken
mutation fails with either of the following errors:

1. TWO_FACTOR_AUTHENTICATION_VERIFICATION_REQUIRED
2. TWO_FACTOR_AUTHENTICATION_PROVISION_REQUIRED

UI knows how to respond accordingly.

2FA provisioning occurs at the 2FA resolver.
2FA verification, currently only OTP, is handled by auth.resolver's
getAuthTokensFromOTP

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Jean-Baptiste Ronssin <65334819+jbronssin@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-23 14:42:01 +02:00
dd5ae66449 Fix: deletion and name updates of attachments in body reflected in Files (#13169)
resolve #13168 , #8501 

This PR fixes an issue where the onChange trigger was deleting all
attachments by removing the JWT token from their paths (if it existed)
and comparing the new body with the old body to identify deleted
attachments. It ensures that only attachments actually removed from the
body get deleted, preventing unintended deletion of attachments not
added directly through the body. It also handles updating attachment
names in the body so changes are reflected in Files, with related tests
updated accordingly.


https://github.com/user-attachments/assets/8d824a24-b257-4794-942e-3b2dceb9907d

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-23 14:36:02 +02:00
7ba8212972 i18n - translations (#13375)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-23 14:01:29 +02:00
Thomas TrompetteandGitHub 015c4477a7 Tt filter step input per variable type (#13371)
- add fieldMetadataId to step output schema
- use it to display FormFieldInput in Filter input
- few fixes for a few fields

Next step:
- Handle composite fields
- Design review
2025-07-23 13:54:06 +02:00
Paul RastoinandGitHub a0a575fa0b Improve FieldMetadataEntity defaultValue, settings and options typing (#13320)
# Introduction
Following https://github.com/twentyhq/twenty/pull/13264, this PR
introduces several `fieldMetadataEntity` typing enhancement suggestions.

Mainly any nullable field metadata entity properties are now either
nullable or defined.
Or never if field is dynamically required or not depending on the field
metadata type

This enhance DevX

## Standards

- field enum ( `MULTI_SELECT`, `SELECT`, `RATING` ) will never have
`options` set to `NULL` in db
- field `RELATION` or `MORH_RELATION` won't ever have its relation
fields set to `NULL` in db
- field of any type `settings`, even if possibly defined, can still be
`NULL` in db
- field of any type `defaultValue`, even if possibly defined, can still
be `NULL` in db

It coud be interesting to guard these standards by adding dedicated pg
constraints on each field

## TypesScript type tests
added coverage for each `settings`, `defaultValue`, and `options`
depending on the current `fieldMetadata`
Honestly I don' know if this typescript assertions test file is not
overkill, but regarding metadata staticness it might be very interesting
to have this guard

## Possible improvements
- We could type as `unknown` instead of "all" on `FieldMetadataType`
inferrance
- We still need to deprecate remaining duplicated entities such as
`Index/Field/MetadataInterface` etc not a huge refactor neither urgent
2025-07-23 13:43:27 +02:00
602e446337 Fix: Infinite "ONGOING" Status in Messaging Message List Fetch (#13370)
## Problem
Previously, the newly created "message list fetch process" left the
message channel in an "ONGOING" status indefinitely.

## Why
Before only "fullSync" messageChannel were concerned by this method.
What happened it sometimes the providers gave empty messageExternalIds
during the initial fetch. Happens for a newly created email account on
gmail or microsoft (not sure which one)

Now that we gather both of sync methods (partial and full) we cannot use
this anly longer. Because after the first sync, if no new messages
arrived in the last 5 minutes, there will be none, so it was consiedered
as emptyMailbox (which is wrong)

## Solution
Removed this logic from the messageChannel since now we will rely on
each messageFolder (messageList) to handle the logic of going for a full
or not sync.

## Question
We might see some bugs in case some newly created email account without
messageList in case the provider does not give a nextSyncCursor at the
messageList level. Not easy to test

## Bonus
We also cleant a useless service method called getCursor that was not
used anywhere.

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-07-23 11:30:08 +00:00
Paul RastoinandGitHub 5ac5e269e3 FIx main typecheck (#13374)
Related to https://github.com/twentyhq/twenty/pull/13357
Ci run on a previous main version, forcing the rebase would have detect
the regression
2025-07-23 13:17:12 +02:00
f841db9042 i18n - translations (#13373)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-23 12:21:13 +02:00
Antoine MoreauxGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
d27fae1dfd fix(approved-access-domain): Improve ux (#13367)
Fix #13324

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-07-23 11:58:01 +02:00
WeikoandGitHub 0ef7e6db85 Move getSchemaName to util (#13357)
## Context
The method was very simple and deterministic, I'm moving its logic to a
util so we don't have to import a service to use it.
2025-07-23 11:45:15 +02:00
Nabhag MotivarasandGitHub 2730b3ea3d copy to clipboard on MultiItemFieldMenuItem (#13292)
# ISSUE

- closes #13089
2025-07-23 11:43:16 +02:00
ac8dab279a i18n - translations (#13372)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-23 11:38:16 +02:00
MarieandGitHub bd9c54b85b Fix userFriendlyMessage not showing for fieldMetadata (#13369) 2025-07-23 11:33:40 +02:00
Baptiste DevessierGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
924e599cba Open filters in side panel (#13304)
In this PR:

- Open filters in the side panel for **workflows**
- Open filters in the side panel for **workflow versions**
- Preparation for opening filters in the side panel for **workflow
runs**
- Add many tests to increase the coverage

Remaining to do:

- Open filters in the side panel for **workflow runs**
- Upon filter creation, open it in the side panel

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-07-23 10:30:08 +02:00
martmullandGitHub eeade6e94c 13303 workflow clean workflowruns to keep max 1000 workflowruns per workflow (#13353)
- add a cron to remove COMPLETED and FAILED workflowRuns if there is
more that 1000 per workflow
- update workflowRun naming computing
2025-07-22 19:45:48 +00:00
332c3a04bb Fix critical bug in MessagingMessageListFetchService (#13350)
## Bug description

All old messages were deleted after the first partial sync because the
diff between the existing messages and the messages returned from the
fetch was done considering that it was always a full sync (ie, that we
always retrieve the full list of message ids). But in a partial sync,
only the new messages appear in the list.

This bug was introduced by https://github.com/twentyhq/twenty/pull/13302
when trying to merge the logic between the full sync and the partial
sync.

## Fix

The fix is to adapt the behavior to the type of sync, by looking at the
presence of the sync cursor.

---------

Co-authored-by: Guillim <guillim@users.noreply.github.com>
2025-07-22 18:19:10 +00:00
Antoine MoreauxandGitHub 5cb163daa1 fix(ui): keep 2 components for chip (#13359) 2025-07-22 16:51:34 +00:00
martmullandGitHub 01805cc71c 13227 workflow wrong completed workflowrun state when multiple branches (#13344) 2025-07-22 17:51:03 +02:00
Lucas BordeauandGitHub dc617177a9 Fixed critical bug with record title cell opening (#13355)
This PR fixes a critical bug on record title cell opening when there was
no view loaded before.

This happened because the hook that opens the record title cell was
relying on a state that stored field definitions that were computed only
when a view was loaded.

Since there is no view on a record page, this wasn't working.

We should refactor field / column definitions so that they are always
derived from either view fields or an object metadata item's field
metadata items.

Fixes https://github.com/twentyhq/twenty/issues/13347
2025-07-22 17:48:03 +02:00
4d2fcf33a3 i18n - translations (#13354)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-22 17:36:14 +02:00
Antoine MoreauxandGitHub 153739b9c3 feat(ai): add current context to ai chat (#13315)
## TODO

- [ ] add dropdown to use records from outside the context
- [x] add loader for files chip
- [x] add roleId where it's necessary
- [x] Split AvatarChip in two components. One with the icon that will
call the second with leftComponent.
- [ ] Fix tests
- [x] Fix UI regression on Search
2025-07-22 17:27:19 +02:00
Paul RastoinandGitHub d46a076aa0 fix(server): plan reserved keyword (#13352)
close https://github.com/twentyhq/twenty/issues/13346
2025-07-22 17:07:03 +02:00
WeikoandGitHub 04db0d2b7e Fix rest metadata api (#13343)
Regression introduced in https://github.com/twentyhq/twenty/pull/13150
where baseUrl is now used in a new requestContext param for MCP but was
not hydrated for rest metadata api
<img width="1334" height="556" alt="Screenshot 2025-07-22 at 15 52 39"
src="https://github.com/user-attachments/assets/7f13797f-eb23-40ab-87b7-49196e4b9b92"
/>
2025-07-22 16:42:00 +02:00
nitinandGitHub a35e8d3529 Add a note regarding config var documentation (#13345)
https://discord.com/channels/1130383047699738754/1397138267144720474

before:

<img width="826" height="279" alt="Screenshot 2025-07-22 at 19 52 16"
src="https://github.com/user-attachments/assets/35ce608d-f917-4ddd-ab37-0a8e5d7aab4d"
/>

after: 

<img width="869" height="404" alt="Screenshot 2025-07-22 at 19 51 57"
src="https://github.com/user-attachments/assets/ec2c54f5-9ae2-4b1d-abd4-f0d816ffafb6"
/>
2025-07-22 20:06:02 +05:30
e998f6a55d i18n - translations (#13341)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-22 14:22:48 +02:00
20f285d246 [feat]:Added the ability to create a view from Command Menu (#13335)
Fixes - #13307 

**Description** 
This PR adds the feature to create view from the command menu

**Key Changes**
- Added the command in the DEAFULT_RECORD_ACTION_CONFIG
- Created a component which is used in the action when the command is
clicked

**Files Changed**
-
packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
-
packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/components/SeeDeletedRecordsNoSelectionRecordAction.tsx
-
packages/twenty-front/src/modules/action-menu/actions/record-actions/no-selection/types/NoSelectionRecordActionsKeys.ts
-
packages/twenty-front/src/modules/views/view-picker/components/ViewPickerListContent.tsx


**Demo Video**


https://github.com/user-attachments/assets/8e3dc3dd-7f85-4da5-8c4a-6721abb29aff

---------

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
2025-07-22 14:09:59 +02:00
Paul RastoinandGitHub 9d61337396 Fix event emitter and viewGroup (#13340)
Emit an even with an [undefined] entity
2025-07-22 11:52:11 +00:00
0b5bdf1c93 feat: support multiple file upload in Attachments component (#13283)
Closes #13277

## What I Did

- Enabled `multiple` attribute in the file input
- Updated the `handleFileChange` handler to loop through files
- Confirmed that each file is sent via `uploadAttachmentFile`

## Why

This change allows users to upload multiple files at once instead of
doing it one by one.

## Screenshot / Video (Optional)
[Screencast From 2025-07-18
23-58-36.webm](https://github.com/user-attachments/assets/ea191f25-1904-4643-afe2-7029785eebcb)


---
Let me know if you'd like any changes! 💪

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-22 13:49:47 +02:00
Félix MalfaitandGitHub d59604c92d Fix small CI escape issue (#13331)
Fixes #13298
2025-07-22 12:13:53 +02:00
Charles BochetandGitHub 8b5eb04b07 Refactor mail folders (#13302)
## Context

We would like to start leveraging more messageFolders during messageSync
which would allow users to select folders they want to sync on their
mailbox. MessageFolder is an abstraction that means folder for
Microsoft, labels for Gmail, not supported for IMAP.


## What

1) We do not aim to build a FE now but we would like to take it into a
consideration if they have been modified through API. So **out of
scope**
2) MessageFolders will be synced regularly from Gmail, Microsoft. This
is currently partially done and improving it is **out of scope**
3) Change: we were having two synchronization mechanism so far:
FULL_SYNC (first time, or when no cursor is present) and PARTIAL_SYNC
(when we have a cursor, we can fetch the diff since the last pull). This
Full vs Partial mode was a high level concept. We now think it's an
driver implementation detail (and can be inferred from the existence of
a cursor). Why making this change now: as we are trying to pull several
folders, a folder could need a full sync if it had no cursor, and
another a partial if it has one. It does not make sense anymore to have
this full vs partial difference at MessageChannel level
4) Once we are sure this work, we can start syncing different folders on
Gmail side (the case for the user it to be able to fetch Promotion
label)

## Implementation strategy

1) Re-use PartialMessageList implementation / API and rename it to
MessageList at it's more complete
2) re-use driver level fullMessageList methods and call them
messageListWithoutCursor
3) make sure that these method are folder specific

## Tests

### Gmail

- Fresh fetch (without cursor): OK
- Message import: OK
- Additional fetch (with messageChannel cursor): OK

### Microsoft

- Fresh fetch (without cursor): OK
- Message import: OK
- Additional fetch (with messageChannel cursor): OK

### Imap

- Fresh fetch (without cursor): OK
- Message import: OK
- Additional fetch (with messageChannel cursor): OK
2025-07-22 11:20:57 +02:00
MarieandGitHub c8753ae59e Adapt rest api to field permissions (#13314)
Closes https://github.com/twentyhq/core-team-issues/issues/1217

We should only query and return the fields that are readable when using
the rest api.
This is behind a feature flag.
2025-07-22 08:46:43 +00:00
Thomas des FrancsandGitHub f95573ab4c Remove the reference to comments in notes (deprecated) (#13319) 2025-07-21 22:44:00 +02:00
206fb567fa i18n - translations (#13321)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-21 20:53:24 +02:00
martmullandGitHub 96daf5555d Remove useless columns (#13312) 2025-07-21 20:41:05 +02:00
Paul RastoinandGitHub 637b1b628a Replace ObjectMetadataInterface by ObjectMetadataEntity (#13317)
# Introduction
Following https://github.com/twentyhq/twenty/pull/13310
> After this PR merge will create a new one removing the type and
replacing it to ObjectMetadataEntity.

This is it !
2025-07-21 18:37:42 +02:00
GuillimandGitHub 37d7996a04 morph fix (#13311)
Short fix for the morph case. 

Was missing the logic for the joinColumnName: we need to add the
"ObjcectMetadataName" on top the the "FieldMetadataName" for morph
relation like it was designed on fieldmetadata service.

On the typescirpt side: the "as FieldMetadataRelationSettings" is not
ideal but I inherit from the a as FieldMetadataInterface type that does
not know the as FieldMetadataType from its parent. If you have a better
simple idea, let me know.


Note : I think we could refactor a bit this part later on.
2025-07-21 16:29:23 +00:00
WeikoandGitHub e22eef0d68 Add missing emitDestroyEvent implementation (#13316)
Tested with connectedAccount deletion
2025-07-21 18:04:53 +02:00
Paul RastoinandGitHub 1536ed3434 Deprecate ObjectMetadataInterface and improve entity typing (#13310)
# Introduction
Following `FieldMetadataInterface` deprecation in
https://github.com/twentyhq/twenty/pull/13264
As for the previous PR will rename and remove all the file in a
secondary PR to avoid conflicts and over loading this one

## Improvements
Removed optional properties from the `objectMetadataEntity` model and
added utils to retrieve test data

## Notes
By touching to `ObjectMetadataDTO` I would have expected a twenty-front
codegenerated types mutation, but it does not seem to be granular enough
to null/undefined coercion
2025-07-21 15:53:17 +00:00
79f3fbb016 Revert "Connect - Relation on FE Importer (#13213)" (#13313)
This reverts commit cc71394863.

Regression introduced in https://github.com/twentyhq/twenty/pull/13213
The import/export use an upsert logic and when it goes through the
"update" path it fails due to the connect not being implemented yet
(should be in https://github.com/twentyhq/core-team-issues/issues/1230)

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-07-21 15:03:42 +00:00
Raphaël BosiandGitHub f6aa556a16 Create view tables inside the core schema (#13309)
Closes https://github.com/twentyhq/core-team-issues/issues/1246

Created, in core schema:
- View
- ViewField
- ViewFilter
- ViewSort
- ViewGroup
- ViewFilterGroup

Generated migration file.
2025-07-21 16:26:18 +02:00
Paul RastoinandGitHub 1dee9bc800 Remove field metadata interface references (#13305)
# Introduction
Following https://github.com/twentyhq/twenty/pull/13264
> After this PR merge will create a new one removing the type and
replacing it to FieldMetadataEntity.

This is it !
2025-07-21 13:57:14 +02:00
Paul RastoinandGitHub 47b60bd49f Deprecate FieldMetadataInterface (#13264)
# Introduction

From the moment replaced the FieldMetadataInterface definition to:
```ts
import { FieldMetadataType } from 'twenty-shared/types';

import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';

export type FieldMetadataInterface<
  T extends FieldMetadataType = FieldMetadataType,
> = FieldMetadataEntity<T>;
```
After this PR merge will create a new one removing the type and
replacing it to `FieldMetadataEntity`.
Did not renamed it here to avoid conflicts on naming + type issues fixs
within the same PR

## Field metadata entity RELATION or MORPH
Relations fields cannot be null for those field metadata entity instance
anymore, but are never for the others see
`packages/twenty-server/src/engine/metadata-modules/field-metadata/types/field-metadata-entity-test.type.ts`
( introduced TypeScript tests )

## Concerns
- TS_VECTOR is the most at risk with the `generatedType` and
`asExpression` removal from interface

## What's next
- `FielMetadataInterface` removal and rename ( see introduction )
- Depcrecating `ObjectMetadataInterface`
- Refactor `FieldMetadataEntity` optional fiels to be nullable only
- TO DIG `never` occurences on settings, defaultValue etc
- Some interfaces will be replaced by the `FlatFieldMetadata` when
deprecating the current sync and comparators tools
2025-07-21 11:30:18 +02:00
Nabhag MotivarasandGitHub c2a5f95675 fix: to open default view from record detail relation section (#13300)
# ISSUE 

- closes #12483
2025-07-21 10:31:08 +02:00
7843d93e58 i18n - translations (#13294)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-19 11:34:01 +02:00
Charles BochetandGitHub fdc6705a75 Remove old body on note and tasks (#13290)
Fixes: https://github.com/twentyhq/twenty/issues/13110

I'm deprecating note.body and task.body to remove confusion between body
and bodyV2

What will be left but should be done later to avoid breaking changes:
- re-add a body field in the graphql API only that points to the same
bodyV2 field in SQL (need to be handled in fields and filter for note
and task)
- (wait some time)
- remove bodyV2 field
2025-07-19 11:25:49 +02:00
Charles BochetandGitHub 62202af1a9 Fix broken graphql playground (#13287)
Fixes https://github.com/twentyhq/twenty/issues/12991
Also fixes a regression on main where updateEvent are not correctly emit
when calling repository.update()
2025-07-19 09:32:26 +02:00
19dad8f23a i18n - translations (#13285)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-18 21:49:09 +02:00
bd88525575 i18n - translations (#13284)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-18 21:43:30 +02:00
EtienneandGitHub cc71394863 Connect - Relation on FE Importer (#13213)
Done : 
- Relation connect on FE Importer
- Remove templating on SpreadsheetMatchedColumn type
- Remove useless files on import
- Remove AvailableFieldsForImport type + Update SpreadsheetImportField
type and SpreadsheetImportFieldOption


To test : 
- Try import opportunities on Apple wk 
[using this
file](https://github.com/user-attachments/files/21233720/Test.import.-.opportunities-sample.csv)


closes : https://github.com/twentyhq/core-team-issues/issues/1090
2025-07-18 21:43:16 +02:00
Baptiste DevessierandGitHub ae04cc9e6c Fix most e2e tests (#13282)
One test will continue to fail, about the Form node.
2025-07-18 21:40:46 +02:00
Charles BochetandGitHub 191bbb9e12 Prevent field name conflicts (#13280)
Fixes https://github.com/twentyhq/twenty/issues/13184
2025-07-18 21:38:36 +02:00
Vicky WangandGitHub fdf958bb27 Workflow V1 Documentation (w/o video) (#13274)
### PR Summary
- Created a new page for workflow documentation 
- Added cover image to folder 
- Uploaded V1 workflow feature release documentation
2025-07-18 17:11:05 +02:00
Abdul RahmanandGitHub dd24fbe4ee Decouple http node from workflows (#13272)
- Added a generic HTTP request tool, allowing agents and workflows to
make HTTP requests to external APIs with configurable method, headers,
and body.
- Decoupled HTTP request workflow nodes from workflow-specific types and
factories, introducing a generic tool interface.
- Updated agent system prompts to include explicit guidance for the HTTP
request tool, including when and how to use it, and how to communicate
limitations.

### Demo

https://github.com/user-attachments/assets/129bc445-a277-4a19-95ab-09f890f8f051
2025-07-18 16:47:19 +02:00
45655a39b0 i18n - translations (#13281)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-18 15:43:01 +02:00
Lucas BordeauandGitHub 2f9c16f8a7 Add search any field front logic with its feature flag (#13278)
This PR adds the frontend logic to handle the user input of a search any
field value.

It also adds the associated feature flag, that can be modified from the
admin panel.

This PR does not add the filtering part nor the saving on view logic,
which will come in their separate PRs.



https://github.com/user-attachments/assets/6a52c090-b957-46aa-bff7-a90b51109789
2025-07-18 13:38:56 +00:00
ce1d1f5bdd i18n - translations (#13279)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-18 15:26:44 +02:00
56812cce53 Add Create related records to Record standard actions (#13095)
#12924 Add Create related records to Record standard actions
- add the "Create related records" option to the standard Record actions
in the command menu.
- apply to one-to-many relations.
- command should open a side panel with an empty record for the selected
object.

<img width="518" alt="Screenshot"
src="https://github.com/user-attachments/assets/0388aaf9-b974-4ae1-85bf-2966d89cbbec"
/>

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
2025-07-18 15:17:29 +02:00
6e5487ed76 morph dataloader specific (#13259)
In the metadata GraphQL api, we need the resolveField for the
morphRelations. This PR implements this topic.


Fixes https://github.com/twentyhq/core-team-issues/issues/1234

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-17 23:06:45 +02:00
MarieandGitHub 5b13f3096a Fix empty combinedFindManyRecords query (#13267)
Fixes
https://github.com/twentyhq/twenty/issues/13220#issuecomment-3084412760
2025-07-17 23:04:35 +02:00
EtienneandGitHub 21fb68b9e2 Fix workspace folder deletion error (#13270)
context : workspace folder deletion throws error when folder does not
exist (in case, workspace users have not upload any files (profil pic,
workflows, attachments, ...))
-> sentry errors :
https://twenty-v7.sentry.io/issues/6565008010/?referrer=github_integration

solution : check folder existence before deleting

test local and s3 storage : 
- create a workspace and delete workspace
- create a workspace, add an attachment and delete workspace

closes : https://github.com/twentyhq/twenty/issues/10745
closes : https://github.com/twentyhq/twenty/issues/12299
2025-07-17 23:01:02 +02:00
Thomas des FrancsandGitHub abd9f8205b Removed box shadow on draggable cards (used in kanbans) (#13268)
Before

<img width="1788" height="1318" alt="CleanShot 2025-07-17 at 18 53
36@2x"
src="https://github.com/user-attachments/assets/772e7cda-86da-4fa3-8107-d06f821da85b"
/>

After

<img width="1488" height="1164" alt="CleanShot 2025-07-17 at 18 54
04@2x"
src="https://github.com/user-attachments/assets/716a559f-3afb-4759-a8e7-23c6c9421908"
/>
2025-07-17 22:40:54 +02:00
Charles BochetandGitHub 50bb30b0ab Fix workspace and profile picture upload (#13269) 2025-07-17 21:28:51 +02:00
MarieandGitHub 7d49639ba6 [permissions] Fix query of foreign key field (ex: messageId) (#13266)
Issue introduced by [Restrict queried columns to graphql-requested
fields](https://github.com/twentyhq/twenty/pull/13246)
In this query 

```ts
{
  ...
  name 
  messageId
  message {
    id
  } 
}
```

`messageId` was being filtered out from the selected fields as we failed
to link it to an existing field, thus null was always returned.
`message { id }` worked because we already handled connections
correctly.
2025-07-17 18:52:57 +02:00
Lucas BordeauandGitHub 91b1b1796f Fixed missing update in typeorm relations (#13262)
This PR fixes a missing update following up a recent PR #13247 

That broke the admin panel user lookup.
2025-07-17 18:07:38 +02:00
2deac9448e Add db event emitter in twenty orm (#13167)
## Context
Add an eventEmitter instance to twenty datasources so we can emit DB
events.
Add input and output formatting to twenty orm (formatData, formatResult)
Those 2 elements simplified existing logic when we interact with the
ORM, input will be formatted by the ORM so we can directly use
field-like structure instead of column-like. The output will be
formatted, for builder queries it will be in `result.generatedMaps`
where `result.raw` preserves the previous column-like structure.

Important change: We now have an authContext that we can pass when we
get a repository, this will be used for the different events emitted in
the ORM. We also removed the caching for repositories as it was not
scaling well and not necessary imho

Note: An upcoming PR should handle the onDelete: cascade behavior where
we send DESTROY events in cascade when there is an onDelete: CASCADE on
the FK.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-17 18:07:28 +02:00
Paul RastoinandGitHub 4a3139c9e0 Copy patch in twenty-website dockerFile (#13265)
failing run
https://github.com/twentyhq/twenty-infra/actions/runs/16349648173/job/46192749052
2025-07-17 16:02:32 +00:00
Baptiste DevessierandGitHub 0752f24638 Update filter design (#13243)
In this PR:

- Adjust the edges to match the new Figma design
- Properly display the filters for workflows and workflow versions
(replaced shouldDisplayEdgeOptions with isEdgeEditable as we want to
display configured filters on workflow versions, but want to disallow
editing them)
- Wrote a few tests to make coverage pass


https://github.com/user-attachments/assets/d303d338-1938-4efe-b489-5a530d65fb30
2025-07-17 15:36:46 +02:00
MarieandGitHub fca39d317f Restrict queried columns to graphql-requested fields (#13246)
Fixes
https://github.com/twentyhq/core-team-issues/issues/255?issue=twentyhq%7Ccore-team-issues%7C1214.

Until then, in the endpoints of our dynamic schema, we were querying all
columns and then formatting the result by removing the non-requested
fields (fields not mentioned in the graphql Query) from the result.
This is not compatible with field-level permissions that we are about to
introduce because users would see their request denied if they have
restricted rights on any of the fields of the objects they are querying,
even if they did not query it in the first place.
To prepare for this change, we are restricting the list of queried
columns to those made necessary by the graphql query.

I only made the changes in the dynamic schema for now. We will
potentially need to do updates to other part of the app that use
createQueryBuilder directly or not (for instance, when calling
repository methods such as .findOne()), but they mostly regard system
objects that are not subject to permissions or are executed by entities
that bypass permission such as jobs creating People and Companies from
their email sync.
No changes have been brought to existingRecords related logic in the
dynamic schema because @Weiko is currently working on it, so I may need
to adapt the new logic after he is done.

No feature flag have been added so far as this should not change
anything at the moment.
2025-07-17 14:59:41 +02:00
Paul RastoinandGitHub 2fb7390965 Workspace metadata migration v2 runner init file structure and services (#13242)
# Introduction
In this PR we initialize strictly typed services for both schema and
metadata migration runner.
Just scaffolding the file tree and services instances for incoming
parallel development with @Weiko

# Conclusion
Nothing is immuable here ! ( and might change in the future ) main goal
was to avoid upcoming conflicts and share same vision
As always any suggestion are more than welcomed !
2025-07-17 12:11:36 +02:00
530a7dea86 Morph relation : migration builder (#13173)
This PR will create the migration to be run for the morph relations

- We created a dedicated util to generate the column name and refactored
a little the code in order to have less dependencies and a clearer devX
(updated the snapshot that changed because of this)
- Moved the `createMigrationActions` to its own util as well
- Created the `MorphRelationColumnActionFactory` based on the relation
one

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-17 11:39:45 +02:00
Charles BochetandGitHub 0a8a6b652a Increase front coverage (#13251)
As per title!
2025-07-17 09:44:11 +02:00
d27075a3d9 i18n - translations (#13249)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-16 21:45:55 +02:00
11abe5440b feat(ai): add mcp-metadata (#13150)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-16 21:32:32 +02:00
Charles BochetandGitHub b25f50e288 Rework locale computation on BE (#13247)
Context:

Users are complaining to see their workspace in a language they don't
know. This behavior is transient, happens on data model update and
disappear on refresh
I've check the cache for users that got the issue and did not spot any
weird language
==> I think we somehow fallback the the request header locale. I feel we
should always use the userWorkspace.locale, request locale should not be
used in BE in my opinion except for unauthenticated endpoints. I'm also
adding logs to understand the locale issue
In this PR:

rename user.workspaces into user.userWorkspaces which is more correct
improve / simplify LOCALES typing
2025-07-16 18:51:46 +02:00
martmullandGitHub 7fde4944d8 Stop requesting all workflowRun columns to fix out of memory issue (#13241)
Querying only useful columns in enqueue cron job
2025-07-16 17:23:21 +02:00
martmullandGitHub 1fc087aeac 13233 zapier update route to create workflow apikey etc (#13239)
Fix webhook creation utils and some tests
2025-07-16 16:23:35 +02:00
5ba98475d4 i18n - translations (#13234)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-16 13:46:21 +02:00
+11 0c73c9df50 Agent chat file drag and drop (#13226)
- Added drag and drop support
- The AIChatTab component has been refactored into smaller, more focused
components to improve readability, maintainability, and scalability of
the codebase.
- Introduced a custom useAIChatFileUpload hook to encapsulate and manage
file upload logic, promoting code reuse and separation of concerns.

### Demo

https://github.com/user-attachments/assets/c4b2a67a-2736-48ae-9ba8-8e124e4b6069

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: neo773 <62795688+neo773@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: MD Readul Islam <99027968+readul-islam@users.noreply.github.com>
Co-authored-by: readul-islam <developer.readul@gamil.com>
Co-authored-by: Thomas des Francs <tdesfrancs@gmail.com>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Jean-Baptiste Ronssin <65334819+jbronssin@users.noreply.github.com>
Co-authored-by: kahkashan shaik <93042682+kahkashanshaik@users.noreply.github.com>
Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Naifer <161821705+omarNaifer12@users.noreply.github.com>
Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
2025-07-16 13:39:54 +02:00
martmullandGitHub 47386e92a3 22 branches 3 (#13181)
This PR does not produce any functional changes for our users. It
prepares the branches for workflows by:

- decommissioning `output` and `context` fields or `workflowRun` records
and use newly created `state` field from front-end and back-end
- use `stepStatus` computed by `back-end` in `front-end`
- add utils and types in `twenty-shared/workflow` (not completed, a
follow-up is scheduled
https://github.com/twentyhq/core-team-issues/issues/1211)
- add concurrency to `workflowQueue` message queue to avoid weird branch
execution when using forms in workflow branches
- add a WithLock decorator for better dev experience of
`CacheLockService.withLock` usage

Here is an example of such a workflow running (front branch display is
not yet done that's why it looks ugly) ->
https://discord.com/channels/1130383047699738754/1258024460238192691/1392897615171158098
2025-07-16 11:16:04 +02:00
Raphaël BosiandGitHub bf6330469b Add claude.md (#13230)
Generate `claude.md` file with claude code
2025-07-16 11:12:37 +02:00
Lucas BordeauandGitHub b8e0256480 Refactor field and cell old component states (#13217)
This PR refactors fields draft value component state and old component
scoped states still left.

It does not refactor the persistField logic but it will allow it in a
next refactor.

We still have to refactor scoped state used as component states / family
states, not as old states.
2025-07-16 10:54:28 +02:00
58fd1f4623 i18n - translations (#13224)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-16 09:34:58 +02:00
+11 8edf59a521 Feat: Agent chat multi thread support (#13216)
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: neo773 <62795688+neo773@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: MD Readul Islam <99027968+readul-islam@users.noreply.github.com>
Co-authored-by: readul-islam <developer.readul@gamil.com>
Co-authored-by: Thomas des Francs <tdesfrancs@gmail.com>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Jean-Baptiste Ronssin <65334819+jbronssin@users.noreply.github.com>
Co-authored-by: kahkashan shaik <93042682+kahkashanshaik@users.noreply.github.com>
Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Naifer <161821705+omarNaifer12@users.noreply.github.com>
Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
2025-07-16 09:26:40 +02:00
ffcbfa6215 fix: standard object metadata override (#13215)
# Issue

- fix #13156, related #13105

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-16 08:50:14 +02:00
87e494d85f i18n - translations (#13218)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-15 18:01:24 +02:00
neo773GitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix Malfait
3e8fa3120d feat: CalDav Driver (#13170)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-07-15 17:41:23 +02:00
Paul RastoinandGitHub c5a74b8e92 Workspace migration v2 testing (#13136)
# Introduction
Introduced `EachTesting` pattern for the builder unit tests.
As always any suggestions are more than welcomed !


Still need to:
- [x] implem basic tests for field
- [x] create `get-flat-index-field-metadata.mock.ts`
- [x] Implement basic tests for index and index-fields
- [ ] Implem standard edges cases tests TDD style

## Misc
- was https://github.com/twentyhq/twenty/pull/13132 closed due to mess
to rebase on main
2025-07-15 16:08:50 +02:00
2c7a459634 Fix: unexpected behavior when deleting Option A and renaming Option B with Option A's value. (#13204)
resolve #12345
The issue was caused by the delete running after the update, which led
to both the old and new options being deleted when they shared the same
value.

---------

Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
2025-07-15 14:06:27 +00:00
df9d2b57f9 Fixed global hotkey conflict in inputs (#13209)
This PR fixes a focus conflict with global hotkeys, mainly "?" that
opens the shortcut helper dialog.

This fix works but we should maybe think about a more generic approach
in another issue, like disabling global hotkeys when certain types of
components are open (input, dropdown, etc.)

Fixes https://github.com/twentyhq/twenty/issues/13197

---------

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-07-15 14:18:06 +02:00
d916ec0af9 Fix link formatting (#13210)
closes https://github.com/twentyhq/twenty/issues/13207

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-15 10:27:00 +00:00
eed502778a fix: standardize trigger labels to lowercase (#13140)
Updated trigger labels across various components to use lowercase
formatting for consistency. This includes changes in the
WorkflowVisualizerPage, DatabaseTriggerDefaultLabel, and other related
files. The adjustments enhance readability and maintain a uniform style
throughout the application.

---------

Co-authored-by: martmull <martmull@hotmail.fr>
2025-07-15 10:05:45 +00:00
Lucas BordeauandGitHub 3698c683db Refactor dialog old component states (#13186)
This PR refactors dialog old component state management.
2025-07-15 11:32:16 +02:00
GuillimandGitHub 1a81e43286 Moprh-integration-delete (#13165)
Intergartion test dedicated to the delete method
2025-07-15 11:16:19 +02:00
Jean-Baptiste RonssinandGitHub ff3f3d4661 fix(api): Allow deactivation of relation fields (#13202)
_(AI generated)_

### Summary

This PR fixes a validation bug in the GraphQL API that prevented
relation fields from being programmatically deactivated. The validation
was incorrectly triggering a "name cannot be changed" error even when
the update payload did not include a name, making it impossible to
disable the field.

Issue #13200 

### Problem

- The [updateOneField] mutation failed when trying to set `isActive:
false` on a `RELATION` field.
- The root cause was a validation check in
[FieldMetadataValidationService] that compared the incoming `name` with
the existing one. If the input `name` was `undefined`, the check
`undefined !== existingName` would incorrectly fail.
- This created a catch-22 where a field could not be deleted (because it
had to be deactivated first) and could not be deactivated (due to this
validation error).

### Solution

- The validation logic in [field-metadata-validation.service.ts] has
been updated to only check for a name change if a new name is
**explicitly provided** in the input
(`isDefined(fieldMetadataInput.name)`).
- This change correctly enforces the rule that relation field names
cannot be changed, while allowing other properties like `isActive` to be
updated without issue.

### How to Test

1.  Create a custom field of type `RELATION`.
2. Using the GraphQL API, call the [updateOneField] mutation with the
field's ID and the payload `{ "isActive": false }`.
3.  Verify that the mutation succeeds and the field is now inactive.
4.  Call the [deleteOneField] mutation to delete the field.
5.  Verify that the deletion is successful.

### Additional Changes

_to be deleted if not necessary_

- Added a new integration test
[successful-field-metadata-relation-update.integration-spec.ts] to cover
this specific use case and prevent future regressions. The existing test
for failing updates remains untouched and continues to pass.
2025-07-15 10:32:52 +02:00
0cb8533e50 i18n - translations (#13206)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-15 09:02:59 +02:00
+4
Abdul RahmanGitHubRaphaël Bosineo773greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix MalfaitFélix Malfaitgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>github-actionsMD Readul Islamreadul-islamThomas des FrancsGuillimLucas Bordeau
72fd3b07e7 Add file support to agent chat (#13187)
https://github.com/user-attachments/assets/911d5d8d-cc2e-4c18-9f93-2663d84ff9ef

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: neo773 <62795688+neo773@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: MD Readul Islam <99027968+readul-islam@users.noreply.github.com>
Co-authored-by: readul-islam <developer.readul@gamil.com>
Co-authored-by: Thomas des Francs <tdesfrancs@gmail.com>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-15 08:57:10 +02:00
Lucas BordeauandGitHub bba1b296c1 Refactor snackbar old component scoped state (#13183)
This PR refactors the snackbar modules that was using legacy versions of
our state management.

We replace the old states with new ones and also the old scoped context
with component instance context.
2025-07-11 16:05:09 +00:00
69a6f4471e i18n - translations (#13182)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-11 17:01:05 +02:00
Lucas BordeauandGitHub e53e09dfd3 Improved dropdown menu headers for filter and sorts (#13177)
This PR improves dropdown menu headers for filter and sort dropdown in
view bar and editable filter chips.

It adds what's necessary to navigate back or close the dropdown, so that
we don't rely solely on click outside to exit the dropdown.

This PR also refactors the components so that we clearly identify the
two code paths that can use filter dropdowns : view bar and filter chip,
everything that can be DRY stays in the object-filter-dropdown module
but we try to have our wrapping components in each distinct module
instead of blending everything with ternaries inside
object-filter-dropdown module.

The vector search input value wasn't correctly handled across the
different dropdowns, due to a wrong component instance management, since
the dropdown menu header improvement put this into light, I also
refactored the state management of the vector search input.

@Bonapara please check the QA video and tell me if it's ok, I didn't add
dropdown menu header on the advanced filter field list dropdown because
it's a select more than a standalone dropdown, what do you think ?

QA : 


https://github.com/user-attachments/assets/17080f32-f302-436c-937b-3577715b7e84


QA Vector search fix : 



https://github.com/user-attachments/assets/6367bbf6-8a98-4b53-86cf-6ba92be130eb

Fixes https://github.com/twentyhq/core-team-issues/issues/640
Fixes https://github.com/twentyhq/core-team-issues/issues/1206
2025-07-11 14:47:52 +00:00
6285613a25 i18n - translations (#13179)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-11 16:20:40 +02:00
Félix MalfaitandGitHub c3bd73a947 Fix Vite fast refresh warning (#13176)
12:28:18 PM [vite] (client) hmr invalidate
/src/modules/onboarding/components/onboardingSyncEmailsOptions.tsx Could
not Fast Refresh ("onboardingSyncEmailsOptions" export is incompatible).
Learn more at
https://github.com/vitejs/vite-plugin-react-swc#consistent-components-exports

<img width="1464" height="359" alt="Screenshot 2025-07-11 at 13 41 41"
src="https://github.com/user-attachments/assets/c6fc75a4-f638-4002-815d-b92e3e7fd7a8"
/>
2025-07-11 16:01:02 +02:00
Félix MalfaitandGitHub 0a93468b95 Refresh AI model setup (#13171)
Instead of initializing model at start time we do it at run time to be
able to swap model provider more easily.

Also introduce a third driver for openai-compatible providers, which
among other allows for local models with Ollama
2025-07-11 13:09:54 +02:00
Lucas BordeauandGitHub fd13bb0258 Fixes for production (#13164)
This PR fixes two bugs : 
- Some important push item to focus stack calls were setting global
hotkey conflicting keys to true (like open dropdown)
- Icon picker matrix items were broken
2025-07-10 15:47:09 +00:00
GuillimandGitHub bed2c640c5 relation-integration-tests (#13113) 2025-07-10 16:55:36 +02:00
Raphaël BosiandGitHub 77b9217467 Fix backspace shortcut preventing text deletion in command menu search bar (#13157)
Before:


https://github.com/user-attachments/assets/4d3ba0fb-9655-4f06-af14-2a4cab737a4a


After:


https://github.com/user-attachments/assets/f1bbf360-a09f-4440-9d05-2c9dc1f41f1f
2025-07-10 14:55:23 +00:00
518dfa81c6 i18n - translations (#13159)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-10 16:51:09 +02:00
Thomas des FrancsandGitHub b9e5169f5a 1.1 changelog (#13151) 2025-07-10 16:50:59 +02:00
cebd66c124 Fix: Inconsistent Workflow Label Letter Casing #13108 (#13144)
Hi,
I’ve resolved the workflow form-level issue referenced in ID: #13108.
If any changes are required, please let me know—I’ll be happy to work on
them.

![Screenshot from 2025-07-10
11-57-54](https://github.com/user-attachments/assets/073df5ef-6a36-4148-baaa-4efa0ba2e74b)

---------

Co-authored-by: readul-islam <developer.readul@gamil.com>
2025-07-10 16:46:35 +02:00
87b5f5448d i18n - translations (#13154)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-10 15:25:07 +02:00
neo773GitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix MalfaitFélix Malfait
aede38000e feat: SMTP Driver Integration (#12993)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-10 15:17:26 +02:00
Raphaël BosiandGitHub fe9de195c3 Fix record table click outside (#13149)
Fixes https://github.com/twentyhq/twenty/issues/13139 introduced by
https://github.com/twentyhq/twenty/pull/13127

The record table click outside was triggered when it shouldn't have been
(clicking inside a dropdown in the side panel).
This PR fixes it by checking the type of the focused element before
triggering the click outside.
Before, we had a check on the current hotkey scope but I removed this
part during the refactoring and I didn't replace it thinking that it
wasn't useful anymore.

Video QA:



https://github.com/user-attachments/assets/68baa9e6-2593-4840-923b-d631c806d9ea
2025-07-10 14:40:05 +02:00
WeikoandGitHub 4467de1b5c Move apikey/webhook migration command from 1.3 to 1.1 (#13146) 2025-07-10 09:15:31 +00:00
Thomas TrompetteandGitHub 50e402af07 Use view filters operands in step filters + migrate to twenty-shared (#13137)
Step operand will more or less be the same as view filter operand. 

This PR:
- moves `ViewFilterOperand` to twenty-shared
- use it as step operand
- check what operand should be available based on the selected field
type in filter action
- rewrite the function that evaluates filters so it uses
ViewFilterOperand instead

ViewFilterOperand may be renamed in a future PR.
2025-07-10 08:36:37 +00:00
d808cbeed9 i18n - translations (#13143)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-10 07:48:51 +02:00
8310b4ff01 Show tool execution messages in AI agent chat (#13117)
https://github.com/user-attachments/assets/c0a42726-50ac-496e-a993-9d6076a84a6a

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-10 07:45:05 +02:00
e6cdae5c27 feat: add auto-scroll to selected menu items in CustomSlashMenu (#13048)
to resolve the issue #13047 

It's my first contribution, I hope it's good enough!

When using the slash command (/) in the notes editor, a menu of commands
appears. When navigating this menu with the up and down arrow keys, the
selection changes, but the menu itself does not scroll. This means that
as the list of commands is long, items outside the visible area cannot
be seen when selected.


The issue was located in the [CustomSlashMenu.tsx] component. The menu
container didn't have vertical scrolling enabled, and there was no logic
to scroll the active item into the visible area.

The fix involved:

Adding overflow-y: auto to the menu's styled container in
[CustomSlashMenu.tsx].
Modifying the [DropdownMenuItemsContainer] component to accept and
forward a ref using React.forwardRef.
Implementing a useEffect hook in [CustomSlashMenu.tsx] that triggers on
selection change. This hook uses a ref to the items container to call
scrollIntoView({ block: 'nearest' }) on the currently selected menu
item.

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-09 17:01:07 +00:00
7187e77b34 i18n - translations (#13138)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-09 18:50:45 +02:00
Charles BochetandGitHub 7e419337b5 Delete userWorkspace when removed from workspace (#13131)
Fixes https://github.com/twentyhq/twenty/issues/13024
2025-07-09 18:34:50 +02:00
Raphaël BosiandGitHub eba997be98 Replace hotkey scopes by focus stack (Part 6 - Remove Hotkey scopes 🫳🎤) (#13127)
# Replace hotkey scopes by focus stack (Part 6 - Remove Hotkey scopes)

This PR is the last part of a refactoring aiming to deprecate the hotkey
scopes api in favor of the new focus stack api which is more robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798
Part 3: https://github.com/twentyhq/twenty/pull/12910
Part 4: https://github.com/twentyhq/twenty/pull/12933
Part 5: https://github.com/twentyhq/twenty/pull/13106

In this part, we completely remove the hotkey scopes.
2025-07-09 17:21:14 +02:00
0a7b21234b i18n - translations (#13135)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-09 17:21:03 +02:00
a0e7c57a6b i18n - translations (#13134)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-09 17:14:28 +02:00
MarieandGitHub c13bc60dad Improve error handling (#13130)
In the BE we throw custom errors with precise error codes (e.g.
"LABEL_ALREADY_EXISTS") before catching them in filters and rethrowing
BaseGraphQLErrors (standard errors such as NotFoundError, UserInputError
etc.).
In the FE we were grouping sentries based on the error codes but we were
actually grouping by very broad codes such as "NOT_FOUND" or
"BAD_USER_INPUT", extracted from the BaseGraphQLErrors.

To fix that, we update the BaseGraphQLError constructor api to allow to
pass on the CustomError directly and retrieve from it the original code
and store it in existing property `subCode` that we will use in the FE
to send errors to sentry.
This new api also eases usage of `userFriendlyMessage` that is passed on
to the api response and therefore to the FE when CustomError is passed
on directly to the BaseGraphQLError constructor.
2025-07-09 17:13:44 +02:00
484c267aa6 Api keys and webhook migration to core (#13011)
TODO: check Zapier trigger records work as expected

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-07-09 17:03:54 +02:00
Paul RastoinandGitHub 18792f9f74 Workspace migration v2 builder INDEX (#13100)
# Introduction
- Added `INDEX` action generation
- Refactored the naming, mainly `WorkspaceMigrationV2ObjectInput` ->
`FlattenObjectMetadata` and same for field. The transpilation will be
done above, agnostically of the workspace migration

Still need to:
- Create testing toolbox and follow each testing pattern for each
actions and make a complex one ( remove static current tests )
- Handle standard and custom edges cases

Notes:
`workspace-migration-v2/types` and `workspace-migration-v2/utils` could
be located outside of this folder, my hunch is that we will move them
once we work on flatten tranpilers
2025-07-09 16:58:17 +02:00
Charles BochetandGitHub 867619247f Fix relation field unknown target object (#13129)
Fixes https://github.com/twentyhq/twenty/issues/12867

Issue:
when you have a variable `toto` which is: `Record<string, MyType>` and
you do toto['xxx'], this will be typed as `MyType` instead of `MyType |
undefined`

Solutions:
- activate `noUncheckedIndexedAccess` check in tsconfig, this is the
preferred solution but will take time to get there (this raises 600+
errors)
- use a Map: cf https://github.com/twentyhq/twenty/pull/13125/files
- set the type to Partial<Record<string, MyType>>. Drawback is that when
you do Object.values(toto), you'll get `Array<MyType | undefined>`.
Hence why we have to filter these behind


<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/d0a0bfed-c441-4e53-84c2-2da98ccbcf50"
/>
2025-07-09 15:43:11 +02:00
martmullandGitHub 156cb1b52f 13058 workflow with code fail to run (#13118)
- update publishOneServerlessFunction so it does not break the workflow
if failing
- update upgrade documentation to update `docker-compose.yml` when
mutated

Fixes https://github.com/twentyhq/twenty/issues/13058
2025-07-09 14:48:44 +02:00
e84521e7b8 i18n - translations (#13128)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-09 14:22:40 +02:00
EtienneandGitHub fce33004bc Connect logic in Workspace Entity Manager (#13078)
Large PR, sorry for that. Don't hesitate to reach me to have full
context (env. 500lines for integration and unit tests)

- Add connect logic in Workspace Entity Manager
- Update QueryDeepPartialEntity type to enable dev to use connect
- Add integration test on createOne / createMany
- Add unit test to cover main utils
- Remove feature flag on connect

closes https://github.com/twentyhq/core-team-issues/issues/1148
closes https://github.com/twentyhq/core-team-issues/issues/1147
2025-07-09 12:16:28 +00:00
a95ca10f29 i18n - translations (#13126)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-09 14:01:40 +02:00
Thomas TrompetteandGitHub 6e79339e64 Add first filter step version (#13093)
I rebuilt the advanced filters used in views and workflow search for a
specific filter step.

Components structure remains the same, using `stepFilterGroups` and
`stepFilters`. But those filters are directly sent to backend.

Also re-using the same kind of states we use for advanced filters to
share the current filters used. And a context to share what's coming
from workflow props (function to update step settings and readonly)

⚠️ this PR only focusses on the content of the step. There is still a
lot to do on the filter icon behavior in the workflow



https://github.com/user-attachments/assets/8a6a76f0-11fa-444a-82b9-71fc96b18af4
2025-07-09 13:52:07 +02:00
Charles BochetandGitHub 0316c857d8 Remove unwanted workflow fetch on right drawer open (#13122)
There was a mistake in the ActionConfig load, we were trying to fetch a
workflow with the opened recordId (which is not always a workflow)
2025-07-09 13:12:46 +02:00
Lucas BordeauandGitHub 44b9990ba7 Fix refetch cached views after field creation (#13120)
This PR fixes a bug that happened when adding a field to a table right
after a field creation in the data model settings.

This happened because the backend adds the newly created field to all
relevant views without telling the frontend (because we don't have web
sockets yet), so the frontend ended up in a stale state, and when the
user added the field manually to a view the backend rightly threw an
error telling that the view field it already existed.

So the fix is just to refetch all views after a field creation, sparing
us the difficult work of manually updating the Apollo cache.

Fixes https://github.com/twentyhq/twenty/issues/13071
2025-07-09 10:18:15 +00:00
19555aeca8 i18n - translations (#13121)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-09 11:35:53 +02:00
Charles BochetandGitHub 41c737703c Refactor data model settings new field folder (#13119)
Folder renaming
2025-07-09 11:26:05 +02:00
1cb60f943e [field-level permissions] Upsert fieldPermission + use fieldPermission to compute permissions (#13050)
In this PR

- introduction of fieldPermission entity
- addition of upsertFieldPermission in role resolver
- computing of permissions taking fieldPermission into account. In order
to limit what is stored in Redis we only store fields restrictions. For
instance for objectMetadata with id XXX with a restriction on field with
id YYY we store:
`"XXX":{"canRead":true,"canUpdate":false,"canSoftDelete":false,"canDestroy":false,"restrictedFields":{"YYY":{"canRead":false,"canUpdate":null}}}`

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-07-09 08:47:59 +00:00
Félix MalfaitandGitHub 6ba6860e1c Frontend tests improvements (#13115)
Fix warnings and lower coverage by 0.1%
2025-07-09 09:23:26 +02:00
+8
Abdul RahmanGitHubFélix MalfaitJean-Baptiste RonssinPaul RastoinNaiferLucas BordeauDmitry MoiseenkoprastoinEtienneGuillimCharles Bochetgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>github-actionsNiklas Korzgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Raphaël BosiCharles Bochet
6057bdd389 Create custom StreamingRestLink for streaming API requests using @stream directive (#13114)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Jean-Baptiste Ronssin <65334819+jbronssin@users.noreply.github.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: Naifer <161821705+omarNaifer12@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Dmitry Moiseenko <36731450+cxdima@users.noreply.github.com>
Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Niklas Korz <niklas@niklaskorz.de>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-07-08 22:59:04 +02:00
Charles BochetandGitHub 39f6f3c4bb Prevent relation update from settings (#13099)
## Expected behavior

Described behavior regarding: (update | create) x (custom | standard) x
(icon, label, name, isSynced)

**Custom:**
- Field RELATION create: name, label, isSynced, icon should be editable
- Field RELATION update: name should not, icon label, isSynced should
- For other fields, icon, label, name, isSynced should be editable at
field creation | update

To simplify: Field RELATION name should not be editable at update

**Standards**
- Field: create does not makes sense
- Field: name should not, icon label, isSynced should (this will end up
in overrides)

To simplify, no Field RELATION edge case, name should not be editable at
update

**Note:** the FE logic is quite different as the UI is hiding some
details behind the syncWithLabel. See my comments and TODO there


## What I've tested:
(update | create) x (custom | standard) x (icon, label, name, isSynced,
description)
2025-07-08 21:03:38 +02:00
Abdul RahmanandGitHub c8ec44eeaf Agent chat code cleanup (#13088)
This PR addresses feedback from
[PR-13061](https://github.com/twentyhq/twenty/pull/13061).

- Removed redundant type assertion from `apollo.factory.ts`.
- Removed redundant tests: Eliminated test cases that were specifically
added to boost coverage metrics rather than testing meaningful
functionality
2025-07-08 20:48:22 +02:00
Raphaël BosiandGitHub 9eaa8ad517 Replace hotkey scopes by focus stack (Part 5 - Form field Inputs, Pages, Dialog ...) (#13106)
# Replace hotkey scopes by focus stack (Part 5 - Form field Inputs,
Pages, Dialog ...)

This PR is the 5th part of a refactoring aiming to deprecate the hotkey
scopes api in favor of the new focus stack api which is more robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798
Part 3: https://github.com/twentyhq/twenty/pull/12910
Part 4: https://github.com/twentyhq/twenty/pull/12933

In this part, all the last components using hotkey scopes were
refactored.
In the 6th and final part of this refactoring we will be able to
completely remove the hotkey scopes from the codebase.
2025-07-08 20:18:32 +02:00
Lucas BordeauGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
66b633e08e Removed useDropdown and its legacy states (#13111)
This PR removes useDropdown barrel hook and refactors the legacy
useDropdown states to the last version of our recoil component state
management.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-07-08 20:16:15 +02:00
GuillimandGitHub 1bf5139f03 fix relation issue (#13109)
Column Name was also modified for relation instead of "only morph
relation"
2025-07-08 16:18:06 +00:00
9787a6efb6 i18n - translations (#13102)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-08 15:13:02 +02:00
47313c388d Update yarn and remove explicit hardened mode (#13092)
Updates yarn to the latest version 4.9.2 (from 4.4.0).

Also removes the explicit `enableHardenedMode` from yarnrc as it
significantly slows down installation.
This is already enabled automatically for pull requests on Github, thus
preventing lockfile poisoning where it's relevant.

See <https://yarnpkg.com/features/security#hardened-mode>:

> in most cases you won't even have to think about it - the hardened
mode is enabled by default when Yarn detects it runs in a pull request
from a public GitHub repository.

It can additionally be enabled explicitly for specific CI jobs by using
an environment variable, if desired:

> The hardened mode can be set (or disabled) [...] by defining
`YARN_ENABLE_HARDENED_MODE=1|0` in your environment variables

If this is the case, yarn still recommends **not** enabling it
everywhere:

> **DANGER**
>
> The hardened mode makes installs significantly slower as Yarn has to
query the registry to make sure the information contained in the
lockfile are accurate. If your CI pipeline runs multiple jobs, we
recommend disabling the hardened mode in all but one of them so as to
limit the performance impact.

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-07-08 14:57:08 +02:00
Niklas KorzandGitHub 10c9d11e15 Skip front config generation if index isn't writable (#13094)
In certain scenarios, the front directory may not be writable.
When this is the case, writing the patched `index.html` should be
skipped just like when the file does not exist.
For brevity, I have replaced the `existsSync` check with a try-catch
that catches any errors occuring during read
or write of the index file.
The alternative would be `fs.accessSync` with `W_OK`, but that would
still throw an error if the file is not writable so I think it is
reasonable to skip it altogether and go straight for the read and write
attempts.

A specific scenario where the front directory is immutable is NixOS,
where the directory may be located in the read-only nix store.
2025-07-08 13:20:01 +02:00
ccf1d703bf Import - fixes (#13097)
- Fixes : https://github.com/twentyhq/twenty/issues/11623
- Design fix :
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=61976-118483&t=z12YCJg7W7PFMcmg-4

After
<img width="600" alt="Screenshot 2025-07-08 at 11 52 26"
src="https://github.com/user-attachments/assets/744fd40b-bba1-4ed1-b44c-48766a20384d"
/>

Before
<img width="600" alt="Screenshot 2025-07-08 at 11 23 08"
src="https://github.com/user-attachments/assets/b5ef81a8-f4dc-4ba1-8741-b8edec579cc1"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-08 13:17:08 +02:00
5306f9e0e5 i18n - translations (#13098)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-08 12:37:01 +02:00
4a3a897a65 Set createdAt and updatedAt as readonly on the frontend (#13096)
This is not the prettiest fix but it's the 5th time I get the feedback
from a user that these fields should be readonly, let's have a special
case for them

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-08 10:29:46 +00:00
a5deddaffd fieldmetadatatype + featurelfag creation (#13021)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-08 12:23:28 +02:00
EtienneandGitHub 56607c0449 Billing - fix duplicate customer in stripe + subscription constraint violation (#13091)
closes https://github.com/twentyhq/core-team-issues/issues/982
2025-07-08 11:17:59 +02:00
67f0b98002 Pass dropdownId to all closeDropdown calls in MatchColumnToFieldSelect (#13087)
Pass the dropdownId into every closeDropdown() call so the instance ID
is always defined and the error no longer occurs.

---------

Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-08 09:17:42 +00:00
f5835a77e5 fix: prevent LinkAvatarChip from triggering page reload when table cells or inline cells are in edit mode (#12734)
resolve #11075
The issue was that when inline cells or table cells are in edit mode, a
click outside event listener is active, and its callback calls
event.stopImmediatePropagation(). This prevents the onClick of LinkChip
from firing, allowing the browser's default behavior to trigger the 'to'
link and cause a full page reload.

To fix this, I added event.preventDefault() inside each click outside
callback to stop the browser from reloading.

Another possible solution: check if currentTableCellInEditModePosition
or isInlineCellInEditMode is true, and if so:

Either convert the StyledLink in LinkChip into a div

Or set forceDisableClick = true, which falls back to AvatarChip.

Before:


https://github.com/user-attachments/assets/7ffd76fd-988e-484b-bad6-10e0147502c2

After:


https://github.com/user-attachments/assets/18cfbc0e-8af6-4ecc-862e-a2b8f02e2535

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-07-08 09:15:08 +00:00
Paul RastoinandGitHub e722303a2f Migration builder v2 handle RELATION through fields actions (#13076)
# Introduction
In this PR we've mainly refactor the typing to be extending existing
entities.
Also handling relations through the field abstraction layer rather than
a dedicated one. We reverted midway

We then still need to:
- Handle indexing
- Uniqueness
- Add strong coverage and avoid static inline snapshoting as right now +
building a coherent testing set
- Deprecate the `standardId` in favor of a `uniqueIdentifier` on each
`objectMetadata` and `fieldMetadata`
- Rename types `input` to `flattened`
- Handle custom or non custom edit edge cases. ( e.g cannot delete a
standard field or object )


## Notes
Right I preferred including too many information ( whole object and
field input ) in the action context, we might wanna evict redundant
information in the future when implementing the runners
2025-07-08 10:24:24 +02:00
Jean-Baptiste RonssinandGitHub ebaec00cce fix: blockquote icon in slash menu (#13068)
This PR fixes a UI bug where the "Quote" item in the slash command menu
was displayed without an icon.


The root cause was that the IconBlockquote component, while available in
the icons library, was not being exported from the internal twenty-ui
package.

## Before / After


![Before](https://github.com/user-attachments/assets/afd5e848-b6a4-4af9-a01d-15c6128f8535)


![After](https://github.com/user-attachments/assets/2468371f-fdd6-42a0-b04b-61a51d286746)


## Changes:

- Exported IconBlockquote from TablerIcons.ts in the twenty-ui package.
- Updated getSlashMenu.ts in the twenty-front package to import and use
the IconBlockquote for the "Quote" menu item.
2025-07-08 10:09:42 +02:00
Félix MalfaitandGitHub 380e8aff86 Remove product hunt (#13090) 2025-07-08 10:07:41 +02:00
65686d7d8a i18n - translations (#13085)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-07 23:01:00 +02:00
martmullandGitHub 2f7d8c76af 22 branches 2 (#13051)
This PR is purely technical, it does produces any functional change to
the user

- add Lock mecanism to run steps concurrently
- update `workflow-executor.workspace-service.ts` to handle multi branch
workflow execution
  - stop passing `context` through steps, it causes race condition issue
  - refactor a little bit
- simplify `workflow-run.workspace-service.ts` to prepare `output` and
`context` removal
- move workflowRun status computing from `run-workflow.job.ts` to
`workflow-executor.workspace-service.ts`

## NOTA BENE
When a code step depends of 2 parents like in this config (see image
below)

If the form is submitted before the "Code - 2s" step succeed, the branch
merge "Form" step is launched twice.
- once because form is submission Succeed resumes the workflow in an
asynchronous job
- the second time is when the asynchronous job is launched when "Code -
2s" is succeeded
- the merge "Form" step makes the workflow waiting for response to
trigger the resume in another job
- during that time, the first resume job is launched, running the merge
"Form" step again

This issue only occurs with branch workflows. It will be solved by
checking if the currentStepToExecute is already in a SUCCESS state or
not

<img width="505" alt="image"
src="https://github.com/user-attachments/assets/b73839a1-16fe-45e1-a0d9-3efa26ab4f8b"
/>
2025-07-07 22:50:34 +02:00
51d02c13bf Feat - Agent chat tab (#13061)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-07-07 22:47:41 +02:00
Antoine MoreauxandGitHub 29f7b74756 fix(ci): reorganize workflow steps and move cache saving to correct s… (#13083)
…tage
2025-07-07 16:06:25 +00:00
MarieandGitHub e4120cdce3 Silent harmless AbortError (#13080) 2025-07-07 15:26:20 +00:00
Raphaël BosiandGitHub c6e5bab4e9 Replace hotkey scopes by focus stack (Part 4 - Inputs) (#12933)
# Replace hotkey scopes by focus stack (Part 4 - Inputs)

This PR is the 4th part of a refactoring aiming to deprecate the hotkey
scopes api in favor of the new focus stack api which is more robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798
Part 3: https://github.com/twentyhq/twenty/pull/12910

In this part, I refactored all inputs in the app so that each input has
a unique id which can be used to track the focused element.
2025-07-07 15:42:12 +02:00
Antoine MoreauxandGitHub 0199d5f72a feat(ci): add GraphQL check workflow and update dependencies setup (#13075) 2025-07-07 14:51:18 +02:00
MarieandGitHub 635300b1dd Fix error handling (#13072)
Fixes
https://twenty-v7.sentry.io/issues/6730499496/?environment=prod&environment=prod-eu&project=4507072499810304&query=is%3Aunresolved%20%21issue.type%3A%5Bperformance_consecutive_db_queries%2Cperformance_consecutive_http%2Cperformance_file_io_main_thread%2Cperformance_db_main_thread%2Cperformance_n_plus_one_db_queries%2Cperformance_n_plus_one_api_calls%2Cperformance_p95_endpoint_regression%2Cperformance_slow_db_query%2Cperformance_render_blocking_asset_span%2Cperformance_uncompressed_assets%2Cperformance_http_overhead%2Cperformance_large_http_payload%5D%20timesSeen%3A%3E10&referrer=issue-stream&sort=date&stream_index=0
2025-07-07 14:22:54 +02:00
f6e38bd280 [POC] Workspace migration builder v2 (#13026)
# Introduction
In this PR we've initialized the `workspace-migration-v2` folder.
Focusing on the builder in the first place.
From now it contains:
- Basic temporary types ( `fieldMetadataEntity` and
`ObjectMetadataEntity` )
- Object actions builder ( create, delete, update )
- Fields actions builder ( create, delete ) ( update coming in a
following PR )

We will still have to handle specific conditions such as:
- Index creation
- Uniqueness addition removal
- Relation

We also need to determine when we want to compute and transpile the
object no field `uniqueIdentifier`

We're aiming to merge this first in order to avoid accumulating code in
this PR

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-07-07 09:59:54 +02:00
Charles Bochet 0d2a196448 Fix yarn patch not being taken into account during build 2025-07-06 21:00:32 +02:00
Charles BochetandGitHub f32bebf7b4 Fix stories (#13069)
As per title
2025-07-06 20:48:02 +02:00
ee8e223aed fix: fixed the update of field metadata label, icon & object (#13064)
This PR is raised to close the issue #13044 

But there are some doubts that needs to be approved.
If the fields are not custom then we were saving the changes in
**standardOverrides** obj in which only three fields are
overridableFields **label, icon & description** can be updated for a
field.

You can see this in _before-update-one-field.hook.ts_ on line 85 
```ts
    const overridableFields = ['label', 'icon', 'description'];
```
If the field to be updated are from these three we are putting this in a
**standardOverrides** obj and passing it

However in our _field-metadata.service.ts_ file. We have **updateOne**
function inside it we have wrote a condition if **isCustom** is false
then the purpose was to build the updatableFields from the
**standardOverrides** obj that we got in **fieldMetadataInput** but
there was an error in it. As you can see below
```ts
 const updatableFieldInput =
        existingFieldMetadata.isCustom === false
          ? this.buildUpdatableStandardFieldInput(
              fieldMetadataInput,
              existingFieldMetadata,
            )
          : fieldMetadataInput;
```
However, the issue was that we were placing the entire
**standardOverrides** object inside **updatableFieldInput** again —
instead of merging its individual fields (label, icon, description)
directly into the update payload.

This PR fixes that by correctly applying the overrides into the
top-level object.

Please refer to the file changes for the full context.

But the thing i don't know. 
[ ] - Is this the correct expected flow?? 
[ ]- Will this change break anything elsewhere?

I still have doubts on these two. Let me know if I missed something.

---------

Co-authored-by: Jagss24 <btwitsjagannat12@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-06 12:47:33 +02:00
Charles BochetandGitHub f65db49514 Fix broken data model translation (#13067)
In this PR, I'm fixing a bug introduced in recent performance work on
the cache.

Bug context: https://github.com/twentyhq/twenty/issues/12865
Related PR opened by a contributor:
https://github.com/twentyhq/twenty/pull/13003

## Root cause

We cache all objectMetadataItems at graphql level : see
`useCachedMetadata` hook:
- instead of going through the regular resolvers, we direlcty load data
from the cache. However this data must be localized regarding labels and
descriptions

In a precedent refactoring, we introduced the notion of locale in the
cache key. However, the user locale was not properly taken into account
as we did not have the information in this hook.

## Fix

1. **Introduce locale in userWorkspace entity**. The locale is stored on
workspaceMember in each postgres workspaceSchema (workspace_xxx) which
is the alter ego of userWorkspace in postgres core schema. Note that we
can't store it in user as a user can be part of multiple workspaces (the
locale already there must be seen as a default for this user), and we
cannot rely on workspaceMember as we would need to query the
workspaceSchema in the authentication layer which we want to avoid for
performance reasons.

2. During request hydration from token (containing the userWorkspaceId),
we fetch the userWorkspace and store it in the Request (this impact both
AuthContext and Request interface)

3. Leverage userWorkspace.locale in the useCachedMetadata hook

## Additional notes

There is no need to change the way we store and retrieve the
object-metadata-maps object itself which is different from the graphql
layer cache. object-metadadata-maps are not localized
2025-07-06 12:18:25 +02:00
70bdb56b4e i18n - translations (#13057)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-04 23:20:18 +02:00
d4620a3fc4 i18n - translations (#13055)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-04 23:07:37 +02:00
EtienneandGitHub e8905be71a Import - Improve phone validation (#12901)
Context : 
- Phones import is a bit complex if not all subfields are provided.
- Phones subfield validation are absent or different from BE validation.

Solution : 
- Normalize callingCode and countryCode validation (BE/FE)
- Ease phone import if only phoneNumber is provided
2025-07-04 23:07:24 +02:00
1386f344dd fix: align workspace switcher button in collapsed navigation drawer (#12893) (#12902)
## Summary
- Fixes #12893 - Workspace switcher button now aligns properly with
record index headers when navigation drawer is collapsed
- Maintains consistent button height in both expanded and collapsed
states
- Simple CSS fix that improves visual consistency

## Fix Details
The issue was caused by the workspace switcher button changing height
from 20px (expanded) to 16px (collapsed). This created misalignment with
the page headers.

Changed in `MultiWorkspacesDropdownStyles.tsx`:
```tsx
// Before - height changed based on drawer state
height: ${({ theme, isNavigationDrawerExpanded }) =>
  isNavigationDrawerExpanded ? theme.spacing(5) : theme.spacing(4)};

// After - consistent height
height: ${({ theme }) => theme.spacing(5)};
```

## Visual Alignment
- Workspace switcher button: 20px height (theme.spacing(5))
- Maintains alignment with record index headers in collapsed state
- Consistent with Figma design requirements

## Test Plan
- [x] Collapsed navigation drawer - workspace switcher aligns with
headers
- [x] Expanded navigation drawer - no visual regression
- [x] Button functionality remains unchanged

---

🤖 This fix was implemented using [Claude Code](https://claude.ai/code)
by Jez (Jeremy Dawes) and Claude working together\!

Thanks to the Twenty team for the great project\! 🚀

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-04 23:06:02 +02:00
324dadca63 feat: enable export of deleted records (#12776)
resolve #12662
This PR enables exporting deleted records by detecting when deleted view
mode is active and adding deletedAt: { is: 'NOT_NULL' } to
graphqlFilter.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-04 22:58:24 +02:00
nitinandGitHub 1729970836 Fix circular structure error in useFetchMoreRecordsWithPagination (#13042)
Fixes:  
TypeError: Converting circular structure to JSON crashing opportunities
pagination.

Issue: 
useFetchMoreRecordsWithPagination was putting an Apollo client object in
React's dependency array. React tried to serialize it for memoization,
hit circular refs in InMemoryCache, and was throwing the error.

Fix: 
Removed unnecessary Apollo client import. The fetchMore from the
original useQuery is already bound to the correct client.

before: 


https://github.com/user-attachments/assets/0422c57b-5cd2-4c0f-9828-fb7bbd7f94c1

after:



https://github.com/user-attachments/assets/20112fb7-3990-4c34-bf39-8c53b7b48e45
2025-07-04 21:53:18 +02:00
Lucas BordeauandGitHub b24588d648 Fix workflow title cell not opening (#13052)
This PR fixes a bug that forced all title cell to behave as if they were
in a show page, but we have workflow page breadcrumb that is not a show
page title.

Fixes https://github.com/twentyhq/twenty/issues/13041
2025-07-04 18:43:05 +02:00
f272394595 i18n - translations (#13049)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-04 16:35:17 +02:00
Lucas BordeauandGitHub 0dcfca2ba3 Fixes greater than or equal and less than and equal filters (#13033)
This PR fixes a mismatch between the filter operation we have on NUMBER
and RATING field types, and the labels we use for those filters in the
application.

What is actually used is : 
- Greater than or equal
- Less than or equal

But unfortunately, until now we display "less than" and "greater than"
everywhere.

This PR fixes that.

We would still have to change the value that is saved in viewFilter
table from `greaterThan` to `greaterThanOrEqual` and likewise for less
than, but it would require a careful migration, and for now just
changing the display labels is enough.

See follow-up issue for migration of the DB values :
https://github.com/twentyhq/core-team-issues/issues/1196

Fixes https://github.com/twentyhq/twenty/issues/13000
2025-07-04 16:26:19 +02:00
Lucas BordeauandGitHub 8a5a9554d9 Fix phone input clearing its value when hitting space (#13031)
This PR fixes a bug with phone input clearing its value when we press
space right after a country calling code.

As the problem comes from the library `react-phone-input-number` this PR
implements a yarn patch.

Fixes https://github.com/twentyhq/twenty/issues/12903
2025-07-04 16:13:16 +02:00
Baptiste DevessierandGitHub 7a2b6bd4d6 Prevent testing malformed workflows and allow testing workflows with cron trigger (#13045)
## Before


https://github.com/user-attachments/assets/ca0c50af-f759-4466-a262-ad8bdd548b89

## After



https://github.com/user-attachments/assets/647a2181-bf28-4a0b-ab3f-faaf13a0f1d6
2025-07-04 15:59:38 +02:00
333b51b18c i18n - translations (#13040)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-04 12:01:02 +02:00
Baptiste DevessierandGitHub 43c3d114bb Pretty format webhook payload example + unify expected body validation (#13034)
## Webhook Expected Body is automatically pretty formatted


https://github.com/user-attachments/assets/0ca7d621-0c6e-4bef-903f-859efd02f9cc

## Expected body fields can't contain spaces in keys' name


https://github.com/user-attachments/assets/b68d36a6-acd4-4ba2-a99a-5857e30c8582

Closes https://github.com/twentyhq/core-team-issues/issues/1117
2025-07-04 11:45:14 +02:00
martmullandGitHub 92576aec0f Fix update context and stepOutput when step running (#13030)
add a function to only set stepStatus, and not context or output. Useful
when setting step state to RUNNING
2025-07-04 10:09:54 +02:00
Antoine MoreauxandGitHub e5522c8efe feat(ai): add mcp integration (#13004) 2025-07-03 21:23:58 +02:00
Baptiste DevessierandGitHub bc94d58af7 Add empty state to multi select input (#13029)
Took inspiration from `RecordPickerNoRecordFoundMenuItem`.

## Before


https://github.com/user-attachments/assets/a8056418-d225-4cd1-b3b8-d7a9792c4f92

## After


https://github.com/user-attachments/assets/126681cd-def4-48d7-a93e-99674993c90e
2025-07-03 16:38:54 +02:00
50ab46cf2a i18n - translations (#13028)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-03 15:00:29 +02:00
MarieandGitHub 288f0919db Define server error messages to display in FE from the server (#12973)
Currently, when a server query or mutation from the front-end fails, the
error message defined server-side is displayed in a snackbar in the
front-end.
These error messages usually contain technical details that don't belong
to the user interface, such as "ObjectMetadataCollection not found" or
"invalid ENUM value for ...".

**BE**
In addition to the original error message that is still needed (for the
request response, debugging, sentry monitoring etc.), we add a
`displayedErrorMessage` that will be used in the snackbars. It's only
relevant to add it for the messages that will reach the FE (ie. not in
jobs or in rest api for instance) and if it can help the user sort out /
fix things (ie. we do add displayedErrorMessage for "Cannot create
multiple draft versions for the same workflow" or "Cannot delete
[field], please update the label identifier field first", but not
"Object metadata does not exist"), even if in practice in the FE users
should not be able to perform an action that will not work (ie should
not be able to save creation of multiple draft versions of the same
workflows).

**FE**
To ease the usage we replaced enqueueSnackBar with enqueueErrorSnackBar
and enqueueSuccessSnackBar with an api that only requires to pass on the
error.
If no displayedErrorMessage is specified then the default error message
is `An error occured.`
2025-07-03 12:42:10 +00:00
Lucas BordeauandGitHub 1f1318febf Fix a hotkey scope race condition in command menu (#13025)
Fixes https://github.com/twentyhq/twenty/issues/12885

This PR fixes a hotkey scope race condition happening on note/task
creation.

The problem is that `ActivityRichTextEditor` catches the click event
before the title cell.

So here we prevent this from happening by checking if the record title
cell is.

This is only temporary and should be improved after the persist logic
refactor : https://github.com/twentyhq/core-team-issues/issues/192
2025-07-03 14:04:37 +02:00
Thomas TrompetteandGitHub 74c8ab422b Add relations to form record output (#13023)
When we use a record field in a form, record relations are displayed as
available variables in following step.
But those are actually empty at execution.

When choosing the record in the form and submitting, we enrich the
record id with the full record before starting the workflow again. But
we were not adding the relations to that enrichment.
2025-07-03 13:21:32 +02:00
d9a4f43afb i18n - translations (#13019)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-03 10:38:05 +02:00
martmullandGitHub 51cb35a27a 22 branches data migration (#13006)
This PR does not produce any functional change

First step of the workflow branch feature

- add gather `workflowRun.output` and `workflowRun.context` into one
column `workflowRun.runContext`
- add a command to fill `runContext` from `output` and `context` in
existing records
- maintain `runContext` up to date during workflow runs
2025-07-03 10:18:33 +02:00
29dbd3fc25 fix long activity panel in deleted record details (#12854)
closes #11978

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-03 00:20:33 +02:00
4d55f4e990 i18n - translations (#13013)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-07-03 00:01:11 +02:00
fb9b61c8c4 fix: updated naming convention in action & object label (#12935)
Fixed the naming convention at object-level permissions. Removed the
_Records on_.
Only [Action] + [Object Name] (e.g. "See Companies") will be shown


![image](https://github.com/user-attachments/assets/8ffb83b0-24fb-4c48-bb0f-3df367d5c193)

Closes #12906

Co-authored-by: Jagss24 <btwitsjagannat12@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-02 23:53:22 +02:00
Michael AandGitHub 5e18438f4c Update docker entry point parsing to handle postgres query paramaters (#12937)
This PR fixes the database name check to ignore query params.
This is useful for situations where you need to force sslmode, like
?sslmode=require. Yarn seems to handle this, but this db creation check
fails.

My environment enforces ssl for all PG connections, so I need twenty to
handle this check for me to test it locally.
2025-07-02 23:22:08 +02:00
nitinandGitHub 3801785d02 Fix Apollo client routing for view operations in field metadata hooks (#13012)
closes https://github.com/twentyhq/twenty/issues/13010
2025-07-02 23:10:26 +02:00
41becaaea4 Refactor migration runner within transaction (#12941)
Modifying the data-model can sometimes fail in the middle of your
operation, due to the way we handle both metadata update and schema
migration separately, a field can be created while the associated column
creation failed (same for object/table and such). This is also an issue
because WorkspaceMigrations are then stored as FAILED can never really
recovered by themselves so the schema is broken and we can't update the
models anymore.
This PR adds a executeMigrationFromPendingMigrationsWithinTransaction
method where we can (and must) pass a queryRunner executing a
transaction, which should come from the metadata services so that if
anything during metadata update OR schema update fails, it rolls back
everything (this also mean a workspaceMigration should never stay in a
failed state now).
This also fixes some issues with migration not running in the correct
order due to having the same timestamp and having to do some weird logic
to fix that.

This is a first step and fix before working on a much more reliable
solution in the upcoming weeks where we will refactor the way we
interact with the data model.

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-07-02 19:21:26 +02:00
8cbb1aa71a Miscrosoft Client errors when refreshing accessToken (#12884)
# Context

We had an error saying "Unknown error importing calendar events for
[...]: Access token is undefined or empty. Please provide a valid token.
For more help -
https://github.com/microsoftgraph/msgraph-sdk-javascript/blob/dev/docs/CustomAuthenticationProvider.md
"

Reason is that the access token method for microsoft is a bit different
than the one from google. And in microsoft case, we want to check the
access token in the authProvider in case it fails. Currently it was not
catched, so it broke services above that counted on the accesstoken to
be valid.

That ended in UNKNOWN failure for our calendar event fetch service.

# Solution

This PR should solve the issue since :
1. forcing the method to break if accesstoken renewal fails
2. logs will help to know what kind of errors will be sent in case we
need to tackle this issue again
3. we now throw TEMPORARY error instead of unknown, allowing 3
getClientConfig failure before it is definitive

Why so many changes while it should have been simple :
The root cause is the `authProvider` from
`'@microsoft/microsoft-graph-client'` npm package. It does not throw a
custom error, and we cannot catch it on calling `Client.init`. Errors
only occurs when the client from
```
const client = this.microsoftOAuth2ClientManagerService.getOAuth2Client(refreshtoken) 
```
is used, as in `client.api('/messages').get().catch(err => [...])`

So we need to go in every call using the client and catch errors, and
rethrow whenver we need as a newly created message type
`MessageImportDriverExceptionCode.CLIENT_NOT_AVAILABLE`


We discussed 1. and 2. with @bosiraphael already
I added 3. to make our system more robust without waiting for more
failures

# Related

Fixes : https://github.com/twentyhq/twenty/issues/12880

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-02 19:03:13 +02:00
0a8670a223 fix: update customize fields navigation to go directly to object detail page (#12904)
## Summary
- Updates "Customize fields" button navigation to go directly to the
specific object's detail page
- Changes navigation from `SettingsPath.Objects` to
`SettingsPath.ObjectDetail`
- Aligns with existing behavior of "Edit Fields" functionality

## Problem
When clicking "Customize fields" in the record table header plus button
dropdown, users were taken to the general objects list page instead of
the specific object's fields page, making it harder to find and
customize the relevant object.

## Solution
Changed the navigation path from `SettingsPath.Objects` to
`SettingsPath.ObjectDetail` in `RecordTableHeaderPlusButtonContent.tsx`,
which takes users directly to the object-specific fields page where they
can see and manage all fields for that object.

## Screenshots

### Before: Customize Fields Dropdown
When clicking the "+" button in the table header, the dropdown shows
"Customize fields" option:

\![Customize Fields
Dropdown](https://github.com/user-attachments/assets/customize-fields-dropdown-fixed.png)

### After: Direct Navigation to Object Fields
Clicking "Customize fields" now navigates directly to the specific
object's fields page:

\![Companies Object Detail
Page](https://github.com/user-attachments/assets/companies-object-detail-page-fixed.png)

## Test plan
- [x] Navigate to any record table view (e.g., People, Companies)  
- [x] Click the "+" button in the table header
- [x] Click "Customize fields"
- [x] Verify navigation goes directly to that object's fields page
instead of the general objects list
- [x] Confirmed the URL is `/settings/objects/{objectNamePlural}` (e.g.,
`/settings/objects/companies`)

Fixes #12835

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Jez (Jeremy Dawes)

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-02 18:54:17 +02:00
a7b9a0710e Replaced useDropdown calls by useCloseDropdown, useOpenDropdown and useToggleDropdown (#12958)
This PR replaces the many calls of useDropdown by the new standalone
hooks : useCloseDropdown, useOpenDropdown and useToggleDropdown.

This will allow to remove useDropdown and then the dropdown recoil
component state v1.

A big round of QA has been made, with some bugs caught along the way.

Closes https://github.com/twentyhq/core-team-issues/issues/1155
Closes https://github.com/twentyhq/core-team-issues/issues/618

## QA

Component|Status|Comment
|---|---|---|
CurrentWorkspaceMemberFavorites|Ok|
FavoriteFolderPickerFooter|Ok|
AdvancedFilterAddFilterRuleSelect|Ok|
AdvancedFilterRecordFilterGroupOptionsDropdown|Ok|
AdvancedFilterRecordFilterOperandSelectContent|Ok|
AdvancedFilterRecordFilterOptionsDropdown|Ok|
useAdvancedFilterFieldSelectDropdown|Ok|
ObjectFilterDropdownBooleanSelect|Ok|
ObjectFilterDropdownOptionSelect|Ok|
ObjectOptionsDropdown|Ok|
ObjectOptionsDropdownLayoutContent|Ok|
ObjectSortDropdownButton|Ok|
useCloseSortDropdown|Ok|
FormDateTimeFieldInput|Ok|Bug detected, cannot select a month or a year,
see issue https://github.com/twentyhq/twenty/issues/12922
FormSingleRecordPicker|Ok|
MultiItemFieldMenuItem|Ok|
RecordDetailRelationRecordsListItem|Ok|
RecordDetailRelationSection|Ok|
RecordDetailRelationSectionDropdownToMany|Ok|
RecordDetailRelationSectionDropdownToOne|Ok|
RecordTableColumnAggregateFooterDropdownSubmenuContent|Ok|
RecordTableColumnAggregateFooterAggregateOperationMenuItems|Ok|
RecordTableColumnAggregateFooterMenuContent|Ok|
RecordTableColumnAggregateFooterValueCell|Ok|
RecordTableColumnHeadDropdownMenu|Ok|
RecordTableHeaderPlusButtonContent|Ok|
useTriggerActionMenuDropdown|Ok|
MultipleSelectDropdown|Ok|
RecordBoardColumnHeaderAggregateDropdownButton|Ok|
SettingsDataModelFieldSelectFormOptionRow|Ok|
SettingsDataModelNewFieldBreadcrumbDropDown|Ok|
SettingsObjectFieldActiveActionDropdown|Ok|
SettingsObjectFieldInactiveActionDropdown|Ok|
SettingsObjectInactiveMenuDropDown|Ok|
SettingsSecurityApprovedAccessDomainRowDropdownMenu|Couldn’t test|
SettingsSecuritySSORowDropdownMenu|Couldn’t test|
SettingsAccountsRowDropdownMenu|Ok|
SettingsRoleAssignment|Ok|
SettingsServerlessFunctionTabEnvironmentVariableTableRow|Couldn’t test|
MatchColumnToFieldSelect|Ok|
SubMatchingSelectDropdownButton|Ok|Removed conflicting duplicate open
dropdown
SubMatchingSelectRowRightDropdown|Ok|
CurrencyPickerDropdownButton|Ok|
IconPicker|Ok|
DateTimePicker|Ok|
PhoneCountryPickerDropdownButton|OK|
Select|Ok|
Dropdown|Ok|Not QAing all dropdowns in the app because the ones of this
QA are enough to show up that Dropdown is behaving correctly on a lot of
use cases
DropdownMenuInnerSelect|Ok|
TabList|Ok|Removed onClickOutside called in dropdown clickable
component, validated with Raph who recently worked on this
DateInput|Ok|
MultiWorkspaceDropdownDefaultComponents|Ok|
AdvancedFilterChip|Ok|
EditableFilterDropdownButton|Ok|
UpdateViewButtonGroup|Ok|
ViewBarDetailsAddFilterButton|Ok|
ViewBarFilterButton|Ok|
ViewBarFilterDropdown|Ok|
ViewBarFilterDropdownAdvancedFilterButton|Ok|
ViewPickerDropdown|Ok|
ViewPickerListContent|Ok|
ViewPickerOptionDropdown|Ok|
WorkflowEditTriggerDatabaseEventForm|Ok|
WorkflowVariablesDropdownWorkflowStepItems|Ok|
AttachmentDropdown|Ok|
SupportDropdown|Ok|

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-02 18:38:45 +02:00
a19a73a977 Fix: Remove white gap in workflow HTTP headers input field (#12812)
Closes #12751 

<img width="500" alt="Screenshot 2025-06-24 at 3 39 33 PM"
src="https://github.com/user-attachments/assets/a7b28fcb-8ba4-40c8-872e-8de8ce5286be"
/>

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
2025-07-02 16:34:52 +00:00
Jeremy LimandGitHub 07f75180ae [#12744] UI Fix: Filter Section Separator Needs to Be Darker (#12945)
[#12744] UI Fix: Change text color in Filter Section Separator from
light to tertiary.

Before
<img width="316" alt="Screenshot 2025-06-29 at 6 10 50 PM"
src="https://github.com/user-attachments/assets/09c21571-24a2-4459-bf0f-4d7e7b4dcf04"
/>


After
<img width="322" alt="Screenshot 2025-06-29 at 6 11 15 PM"
src="https://github.com/user-attachments/assets/a4c486c9-34ae-4f10-83cb-918b15582dec"
/>
2025-07-02 17:50:10 +02:00
Thomas TrompetteandGitHub b59235409e Turn filter action into conditions (#13005)
Previous logic was using the previous step output and filtering items
that were passing filters.
What we actually want is:
- send filters, right operand being always a step output key, left
operand being either a key, either a value
- resolve those filter variables
- apply the filters to decide whether the condition is passed or not
2025-07-02 15:29:52 +00:00
Félix MalfaitandGitHub 9f0b8809cb Dates beyond 2030 and autoscroll in select (#12998)
We got several requests to be able to set dates beyond 2030 which seems
reasonable from a business standpoint! The problem was that then it
required scrolling to get to the current date so a bad UX for most
cases. I forced re-selecting the item to trigger auto scroll
2025-07-02 17:21:13 +02:00
Baptiste DevessierandGitHub e8a2d71844 Scaffold filters creation and deletion (#12990)
When the feature flag is activated, we can now create filters and delete
them. This PR mainly updates how we generate workflow diagrams.


https://github.com/user-attachments/assets/1a4aef46-7c3c-45fa-953f-0bd1908b9be7
2025-07-02 17:01:44 +02:00
EtienneandGitHub ba67e0d5f4 Connect - Update Gql schema generation (#13001)
To test : 

```
mutation testMutation {
  createPerson(
    data: {company: {connect: {where: {domainName: {primaryLinkUrl: "airbnb.com"}}}}}
  ) {
    id
  }
}
```

closes https://github.com/twentyhq/core-team-issues/issues/1167
2025-07-02 14:37:24 +00:00
Lucas BordeauandGitHub 54e233d7b9 Fix bug date picker month and year dropdown not clickable (#12963)
This PR fixes a bug that only happens on workflow form inputs.

Clicking a month or year dropdown in the date picker header, will close
the whole date picker, instead of changing the year or month.

This is because the date picker considers that there is a click outside
happening.

So to fix that we use the excluded click outside id system.

Fixes https://github.com/twentyhq/twenty/issues/12922

See related issue to discuss the improvement of this system :
https://github.com/twentyhq/core-team-issues/issues/1166
2025-07-02 15:19:21 +02:00
7f323aaa16 Fix Raw Json Null Error (#12968)
This pull request refines the `usePersistField` hook in
`usePersistField.ts` to improve handling of raw JSON fields. The changes
ensure that unpersistable raw JSON fields are excluded early in the
logic and simplify the conditions for determining persistable values.

Enhancements to raw JSON field handling:

* Added a conditional check to exit early if the field is both raw JSON
and unpersistable (`usePersistField.ts`).
* Simplified the persistability condition by removing redundant checks
for unpersistable raw JSON fields (`usePersistField.ts`).

---------

Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
2025-07-02 13:08:34 +00:00
Félix MalfaitandGitHub d744ef129e Rebase main before applying breaking change CI (#12992)
Avoid false positives when a breaking change was recently merged and the
PR branch isn't up to date
2025-07-02 07:39:53 +02:00
nitinandGitHub d2ddd6f473 Separate system operations from core objects in GraphQL endpoints (#12977)
Moves system-level operations (auth, billing, admin) to use the
/metadata endpoint instead of /graphql.

This cleans up the endpoint separation so /graphql is purely for core
objects (Company, People, etc.) and /metadata handles all system
operations.

Part of prep work for webhook/API key core migration.
2025-07-01 18:29:32 +02:00
Lucas BordeauandGitHub 76c517aa29 Fixed avatar font weight and associated story (#12989)
This PR changes the avatar placeholder letter font-weight to medium.

I also updated the story to use a symmetric letter “E” instead of “L”,
so that it is easier to spot alignment problems.

Before : 

<img width="347" alt="Capture d’écran 2025-07-01 à 15 51 57"
src="https://github.com/user-attachments/assets/b622083e-b9a8-45a9-9956-a15c0cb3508a"
/>

After :

<img width="257" alt="Capture d’écran 2025-07-01 à 15 53 29"
src="https://github.com/user-attachments/assets/e491af60-cfce-486d-9ee0-6bb4dff0f022"
/>
2025-07-01 17:56:56 +02:00
e832a3a609 Fix Vite stale chunk lazy loading error. (#12984)
This PR fixes a bug that happens when a user tries to load an app chunk
that is not available anymore, because a new build happened between the
moment the user loaded its page and the moment he's requesting a chunk.

Example : 
- The user loads the settings profile page
- He leaves his computer for a few minutes
- The CI triggers a new front build
- The user comes back and tries to navigate to the accounts settings
page
- The page he has loaded only knows the chunk of the previous build and
tries to request it
- Since the server that serves the front chunks has the new chunks it
sends an error
- The code that lazy loads the chunk throws a `TypeError: Failed to
fetch dynamically imported module`

The fix is to trigger a `window.location.reload()` if this error is
thrown. While this is a temporary and imperfect fix it should at least
provide a better UX for the user.

See follow-up issue : https://github.com/twentyhq/twenty/issues/12987

After : 


https://github.com/user-attachments/assets/edd7eda0-cdfa-4584-92bd-2eec9f866ab3

Fixes https://github.com/twentyhq/twenty/issues/12851

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-01 13:02:03 +00:00
9fbff82bf1 Fix search record for workflow objects (#12914)
Fixes: #12722

The problem is that there is no TS_VECTOR field in workflow objects.
Thus, I have added this field to three objects: workflow,
workflowVersions, and workflowRuns.

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-07-01 10:58:13 +02:00
Baptiste DevessierandGitHub 34e9e7d836 Add workflow filters on diagram (#12974)
> [!NOTE]
> The new behavior is hidden behind a feature flag. 

## Before


https://github.com/user-attachments/assets/30c6d001-d9c8-4006-b577-e4e450d58b12

## After


https://github.com/user-attachments/assets/79446976-4508-41d2-8044-4078f67c02e0
2025-07-01 10:35:18 +02:00
Thomas TrompetteandGitHub 7756b472a4 Run workflow version on multiple records (#12969)
Fixes https://github.com/twentyhq/core-team-issues/issues/776

Until we have loops implemented, we still allow the user to select
multiple records for manual trigger. A workflow run will be triggered
for each record selected.

The display of multiple runs in the side panel is not ideal. After
discussion with @Bonapara, we will load all runs into the side panel
until we have the inbox. Once we have the inbox, we will use the side
panel when only one run is triggered.


https://github.com/user-attachments/assets/b563b4f1-0705-45aa-b296-c1b41abf4815
2025-06-30 16:44:41 +02:00
Paul RastoinandGitHub 3e7f2074e5 Fix REST API filters (#12929)
# Introduction
close https://github.com/twentyhq/twenty/issues/12921

### Done here:
- Removed
[check-order-by.utils.ts](https://github.com/twentyhq/twenty/pull/12929/files#diff-d044effc0b77b3b67523595ce0febd786d3a0fd74ae905ce2efc349134d7c7d0)
that was a duplicated
- new debug entry `twenty-server` entrypoint
- fixed the fields name computation in case of a relation field metadata
type
- Updated and refactored coverage both unit and integration


![image](https://github.com/user-attachments/assets/e3f0937a-8b54-4ab5-8348-0cd742c107ea)
2025-06-30 16:29:57 +02:00
MarieandGitHub 1b72d901a5 Improve RestApiExceptionFilter (#12967)
RestApiExceptionFilter is used as an exception filter for the core
controller which is used for crud operations on our objects (equivalent
of our dynamic queries findManyPeople etc. on the graphql API).

Exceptions were leading a 400 / BadRequestException response status
which can be confusing to users.
By default we should actually throw a 500 if the error was not handled
priorily, but we have not implemented input validation for the REST api
so we fear to be flooded with errors that should not be 500 but 400 due
to user inputs. A solution should be brought [with this
ticket](https://github.com/twentyhq/core-team-issues/issues/1027) but it
has not been prioritized yet.
2025-06-30 16:01:48 +02:00
Baptiste DevessierandGitHub d4fe8efd7f Store HTTP request json body as a string (#12931)
Variables can be used without surrounding quotes.

The formatting is also preserved for raw json.

We would have to do additional work if we want to add other types of
bodies, like form data.

## Demo


https://github.com/user-attachments/assets/498dd9c8-6654-4440-9ab0-35bad5e34ca8

Closes https://github.com/twentyhq/core-team-issues/issues/1129

Related to https://github.com/twentyhq/core-team-issues/issues/1117.
Doesn't solve the issue for webhooks but does for http body input.
2025-06-30 15:34:21 +02:00
Thomas TrompetteandGitHub 8272e5dfd0 Add a limit to workflow queue per workspace (#12908)
- new status `ENQUEUED` added. With a command to backfill
- counter in cache per workspace, managed by a new service
[workflow-run-queue.workspace-service.ts](https://github.com/twentyhq/twenty/compare/tt-improve-workflow-run-queueing?expand=1#diff-1e2de2a48cd482a3bd7e8dedf1150a19d0b200afbd9282181a24ecddddb56927)
- cron added that will run every minute to look for not started
workflows

Here is the new flow:
- When executing a workflow, we check if the queue is not full. If not,
run is created as `ENQUEUED` and the run workflow job is triggered as
usual. If full, create the run as NOT_STARTED and do not trigger the job
- Cron will look for NOT_STARTED workflows and queue some if there is
some place again
- Only MANUAL and Form submit skip the queue limit
2025-06-30 14:27:57 +02:00
WeikoandGitHub fcb869fdd9 Fix server integration tests due to expired token (#12966)
Set expiration date to 2035 instead of 2025 for admin jwt token
2025-06-30 14:05:56 +02:00
301eb6e11c i18n - translations (#12952)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-29 22:33:58 +02:00
+12 74b6466a57 feat: Add agent role assignment and database CRUD tools for AI agent nodes (#12888)
This PR introduces a significant enhancement to the role-based
permission system by extending it to support AI agents, enabling them to
perform database operations based on assigned permissions.

## Key Changes

### 1. Database Schema Migration
- **Table Rename**: `userWorkspaceRole` → `roleTargets` to better
reflect its expanded purpose
- **New Column**: Added `agentId` (UUID, nullable) to support AI agent
role assignments
- **Constraint Updates**: 
- Made `userWorkspaceId` nullable to accommodate agent-only role
assignments
- Added check constraint `CHK_role_targets_either_agent_or_user`
ensuring either `agentId` OR `userWorkspaceId` is set (not both)

### 2. Entity & Service Layer Updates
- **RoleTargetsEntity**: Updated with new `agentId` field and constraint
validation
- **AgentRoleService**: New service for managing agent role assignments
with validation
- **AgentService**: Enhanced to include role information when retrieving
agents
- **RoleResolver**: Added GraphQL mutations for `assignRoleToAgent` and
`removeRoleFromAgent`

### 3. AI Agent CRUD Operations
- **Permission-Based Tool Generation**: AI agents now receive database
tools based on their assigned role permissions
- **Dynamic Tool Creation**: The `AgentToolService` generates CRUD tools
(`create_*`, `find_*`, `update_*`, `soft_delete_*`, `destroy_*`) for
each object based on role permissions
- **Granular Permissions**: Supports both global role permissions
(`canReadAllObjectRecords`) and object-specific permissions
(`canReadObjectRecords`)

### 4. Frontend Integration
- **Role Assignment UI**: Added hooks and components for
assigning/removing roles from agents

## Demo


https://github.com/user-attachments/assets/41732267-742e-416c-b423-b687c2614c82

---------

Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Vicky Wang <157669812+vickywxng@users.noreply.github.com>
Co-authored-by: Vicky Wang <vw92@cornell.edu>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-06-29 22:18:14 +02:00
317336ab71 i18n - translations (#12951)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-29 21:45:36 +02:00
neo773GitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix MalfaitFélix Malfait
7c8d362772 feat: IMAP Driver Integration (#12576)
### Added IMAP integration 

This PR adds support for connecting email accounts via IMAP protocol,
allowing users to sync their emails without OAuth.

#### DB Changes:
- Added customConnectionParams and connectionType fields to
ConnectedAccountWorkspaceEntity

#### UI:
- Added settings pages for creating and editing IMAP connections with
proper validation and connection testing.
- Implemented reconnection flows for handling permission issues.

#### Backend:
- Built ImapConnectionModule with corresponding resolver and service for
managing IMAP connections.
- Created MessagingIMAPDriverModule to handle IMAP client operations,
message fetching/parsing, and error handling.

#### Dependencies:
Integrated `imapflow` and `mailparser` libraries with their type
definitions to handle the IMAP protocol communication.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-06-29 21:32:15 +02:00
Paul RastoinandGitHub 3c5595e4ff Nitpick: psl types (#12925)
Close https://github.com/twentyhq/twenty/issues/12917
2025-06-27 14:31:27 +02:00
EtienneandGitHub 8a7a86b3c6 Workspace creation - fix not found file during avatar picture copy (#12920)
Context :
Sentry error -
https://twenty-v7.sentry.io/issues/6563326453/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=issue-stream&sort=date&stream_index=0

If a userWorkspace loses its default avatar picture (how can this
happen? This was spotted for twenty core team userWorkspaces, so it may
be very specific), the user can't create another workspace.

Test : 
- Create a workspace via a signup with a Google/Microsoft account having
a profile pic.
- Delete the profile pic in storage
- Try to create an other workspace
2025-06-27 13:35:42 +02:00
3a9663e3e0 i18n - translations (#12926)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-27 13:20:04 +02:00
EtienneandGitHub b80762b3e1 fix IndexFieldMetadata availability in IndexMetadata/ObjectMetadata in front (#12886)
Context : 
- IndexFieldMetadata was no longer available on 'objects' gql query
([since this PR](https://github.com/twentyhq/twenty/pull/12785)). Then,
unicity checks on import do not work anymore.

Fix : 
- Add a dataloader logic in indexFieldMetadata
- Add extra check in unicity hook on import
2025-06-27 13:12:14 +02:00
Antoine MoreauxandGitHub c3f8a25d25 fix(captcha): simplify captcha token refresh logic (#12876)
Fix
https://twenty-v7.sentry.io/issues/6686753138/events/latest/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=latest-event&sort=date&stream_index=1

Fix captcha invalid
2025-06-27 08:44:10 +00:00
Raphaël BosiandGitHub 3241539db9 Replace hotkey scopes by focus stack (Part 3 - Record Board, Cards and Inline Cells) (#12910)
# Replace hotkey scopes by focus stack (Part 3 - Record Board, Cards and
Inline Cells)

This PR is the second part of a refactoring aiming to deprecate the
hotkey scopes api in favor of the new focus stack api which is more
robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798

The board shortcuts are no longer centralized in the record board, they
are now split and the focused element is in charge of applying the
desired shortcuts.

## Video QA:


https://github.com/user-attachments/assets/20ba4a24-6fc3-4a97-9cd3-68e846699e30
2025-06-26 18:07:54 +02:00
12add0e1f9 i18n - translations (#12913)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-26 18:01:28 +02:00
MarieandGitHub 2d5312276c Improve FE error handling (#12864)
This PR aims at improving readability in sentry and user experience with
runtime errors.

**GraphQL errors (and ApolloError)**
1. In sentry we have a lot of "Object captured as exception with keys:
extensions, message" errors (2k over the last 90d), on which we have
zero information. This is because in apollo-factory we were passing on
GraphQL errors to sentry directly why sentry expects the structure of a
JS Error. We are now changing that, rebuilding an Error object and
attempting to help grouping by creating a fingerPrint based on error
code and truncated operationName (same as we do in the back for 500
graphql errors).
2. In sentry we have a lot of ApolloError, who actually correspond to
errors that should not be logged in sentry (Forbidden errors such as
"Email is not verified"), or errors that are already tracked by back-end
(Postgres errors such as "column xxx does not exist"). This is because
ApolloErrors become unhandled rejections errors if they are not caught
and automatically sent to sentry through the basic config. To change
that we are now filtering out ApolloErrors created from GraphQL Errors
before sending error to sentry:
<img width="524" alt="image"
src="https://github.com/user-attachments/assets/02974829-26d9-4a9e-8c4c-cfe70155e4ab"
/>

**Runtime errors**
4. Runtime errors were all caught by sentry with the name "Error",
making them not easy to differentiate on sentry (they were not grouped
together but all appeared in the list as "Error"). We are replacing the
"Error" name with the error message, or the error code if present. We
are introducing a CustomError class that allows errors whose message
contain dynamic text (an id for instance) to be identified on sentry
with a common code. _(TODO: if this approach is validated then I have
yet to replace Error with dynamic error messages with CustomError)_
5. Runtime error messages contain technical details that do not mean
anything to users (for instance, "Invalid folder ID: ${droppableId}",
"ObjectMetadataItem not found", etc.). Let's replace them with "Please
refresh the page." to users and keep the message error for sentry and
our dev experience (they will still show in the console as uncaught
errors).
2025-06-26 15:54:12 +00:00
EtienneandGitHub ada7933f9b Import - richTextV2 import (#12868)
- Enable markdown import
- Decrease the createMany batch size on import
2025-06-26 17:02:45 +02:00
Lucas BordeauandGitHub 658cd46336 Refactor useDropdown states to component state V2 (#12911)
This PR is a follow-up of the first refactor of dropdown hooks :
https://github.com/twentyhq/twenty/pull/12875

In this PR we continue by focusing on the replacement of those two
states that are still using the v1 of component states :

- isDropdownOpenComponentState
- dropdownPlacementComponentState

When then remove those two old states and now only use the new component
state v2.

## QA


Component | Status | Comments
-- | -- | --
RecordDetailRelationSectionDropdownToMany | Ok |  
RecordDetailRelationSectionDropdownToOne | Ok |  
WorkflowVariablesDropdown | Ok |  
DropdownInternalContainer | Ok | Tested on tables and boards fields
2025-06-26 16:11:24 +02:00
Weiko fd7089cfc5 fix server linter 2025-06-26 15:51:19 +02:00
bb13b4aed0 Add fix schema array type command (#12887)
Following this fix https://github.com/twentyhq/twenty/pull/12874 we now
need to add a command to retroactively fix existing columns

---------

Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: prastoin <paul@twenty.com>
2025-06-26 15:47:58 +02:00
WeikoandGitHub 142ca6b468 Fix upgrade command updating version during dry run (#12909)
Fix upgrade command updating version during dry run
2025-06-26 15:41:13 +02:00
Paul RastoinandGitHub ac71cc3233 fix(server): incr metadata version (#12907)
Following https://github.com/twentyhq/twenty/pull/12883
2025-06-26 15:25:20 +02:00
martmullandGitHub 9256a7f234 Add empty option to select form field (#12898)
## Before

New option selected, but not taken into account

<img width="744" alt="image"
src="https://github.com/user-attachments/assets/880421e2-5582-40f3-809a-ef443517b510"
/>


## After

<img width="750" alt="image"
src="https://github.com/user-attachments/assets/d5114712-a08a-4867-a93c-da5240f81472"
/>
2025-06-26 14:31:51 +02:00
GuillimandGitHub fa09adee8e escaping special chars for events (#12872)
Escaping newly discovered special chars for events

- \x00 is a Unicode for nul
- \x7f is a Unicode for delete

Edit:
i initially, just in case after looking at the logs, i removed the
single quotes as well (there are fobiden in the standard RFC 5545) but
after reflexion other props than icalUID rely on this sanitization so
leaving as such. It should already be taken care of anyway by typeorm


Ref sentry :
https://twenty-v7.sentry.io/issues/6567295627/?environment=prod&environment=prod-eu&project=4507072499810304&query=&referrer=issue-stream&stream_index=13

Fixes https://github.com/twentyhq/twenty/issues/12827
2025-06-26 12:27:26 +00:00
Paul RastoinandGitHub 2d774767c0 Fix standard object computed metadata (#12883)
# Introduction
close https://github.com/twentyhq/twenty/issues/12879

This PR has a global impact all on workspaces
It should be crash tested in local using an anon extract of the db
2025-06-26 13:38:52 +02:00
Thomas des FrancsandGitHub 2ca43e18e9 Removed PH from the README (#12894) 2025-06-26 11:46:09 +02:00
6a391050d3 chore: improve password strength in install script (#12878) (#12896)
## Summary
- Fixes #12878 - Increases PostgreSQL password generation from 16 to 32
bytes
- Improves default security for new installations
- Aligns with the password strength recommendation in the manual setup
documentation

## Change Details
Changed the password generation in
`packages/twenty-docker/scripts/install.sh` from:
```bash
echo "PG_DATABASE_PASSWORD=$(openssl rand -hex 16)" >> .env
```
to:
```bash
echo "PG_DATABASE_PASSWORD=$(openssl rand -hex 32)" >> .env
```

This generates a 64-character hexadecimal password (32 bytes) instead of
a 32-character one (16 bytes), providing significantly better security
for PostgreSQL database passwords in new installations.

---

🤖 This fix was implemented using [Claude Code](https://claude.ai/code)
by Jez (Jeremy Dawes) and Claude working together\!

Thanks to the Twenty team for maintaining such a great project\! 🚀

Co-authored-by: Claude <noreply@anthropic.com>
2025-06-26 11:09:36 +02:00
Raphaël BosiandGitHub 041f2dff4a Enable the opening of email threads and calendar events from the timeline (#12873)
Fixes https://github.com/twentyhq/core-team-issues/issues/1123



https://github.com/user-attachments/assets/18a23d3f-c8c7-4c77-8b81-3685220343a5
2025-06-25 18:07:03 +02:00
1d13b087ed Minor changelog updates + other misc issues (#12882)
^^as per summary written in the title :)

Co-authored-by: Vicky Wang <vw92@cornell.edu>
2025-06-25 17:45:07 +02:00
martmullandGitHub f86b9b12b3 Add placeholder to generate fake form respose (#12871) 2025-06-25 17:21:17 +02:00
Lucas BordeauandGitHub 22b4595b0b Refactor useDropdownV2 (#12875)
# What this PR does

This PR introduces what’s needed to progressively refactor the
useDropdown hooks we have.

It removes useDropdownV2 and renames useDropdown used for multi-page
dropdowns to useDropdownContextStateManagement

## The 3 useDropdown hooks

There are currently 3 useDropdown hooks : 

One is used for managing states in some dropdowns that have multiple
inner pages with contexts and without recoil. It is limited and would
need a separate refactoring, thus I just renamed it.

Then we have useDropdown and useDropdownV2, which followed our multiple
versions of recoil state management wrappers.

Now that the state management has been stabilized, we can merge
everything on the last version.

## What this refactor will allow next

This refactor will allow to refactor the legacy recoil state management,
because useDropdown is depending on legacy recoil states with scopeId.

Because there are only a dozen of those legacy states left, and the
dropdown’s ones are the harder to refactor, because swapping them as-is
causes a big QA, and if we have a big QA to do on all dropdowns, better
refactor the whole dropdown management and have everything clean.

After this refactor, we will be able to delete the legacy dropdown
states, and proceed with the other legacy states, then removing all the
legacy recoil state mangament.

## How do we allow progressive refactoring ?

There are many places where useDropdown is used.

To have an easier refactoring process, we want to merge multiple small
pull requests so that it is easier to QA and review.

For this we will maintain both legacy component state and component
state V2 in parallel for isDropdownOpen, so that the new hooks
`useOpenDropdown` , `useCloseDropdown` are doing the same thing than
`useDropdown` and `useDropdownV2` .

Thus for the moment, whether we use the legacy hooks or the new ones,
the effects are the same.

And we can have dropdowns operating on the old states and the new states
living side by side in the app.

## QA

Component | Status | Comments
-- | -- | --
CommandMenuActionMenuDropdown | Ok |  
RecordIndexActionMenuDropdown | Ok |  
RecordShowRightDrawerOpenRecordButton | Ok |  
useCloseActionMenu | Ok |  
CommandMenuContextChipGroups | Ok |  
useCommandMenuCloseAnimationCompleteCleanup | Ok |  
ObjectOptionsDropdown | Ok |  
ObjectOptionsDropdownContent | Ok |  
ObjectOptionsDropdownFieldsContent | Ok |  
ObjectOptionsDropdownHiddenFieldsContent | Ok |  
ObjectOptionsDropdownHiddenRecordGroupsContent | Ok |  
ObjectOptionsDropdownLayoutContent | Ok |  
ObjectOptionsDropdownLayoutOpenInContent | Ok |  
ObjectOptionsDropdownMenuContent | Ok |  
ObjectOptionsDropdownRecordGroupFieldsContent | Ok |  
ObjectOptionsDropdownRecordGroupsContent | Ok |  
ObjectOptionsDropdownRecordGroupSortContent | Ok |  
RecordBoardColumnHeaderAggregateDropdown | Ok |  
AggregateDropdownContent | Ok |  
RecordBoardColumnHeaderAggregateDropdownFieldsContent | Ok |  
RecordBoardColumnHeaderAggregateDropdownMenuContent | Ok |  
RecordBoardColumnHeaderAggregateDropdownMenuContent | Ok |  
RecordBoardColumnHeaderAggregateDropdownOptionsContent | Ok |  
RecordBoard | Ok | Used closeAnyOpenDropdown instead for a better UX
RecordBoardCard | Ok |  
useRecordBoardSelection | Ok |  
RecordTableColumnAggregateFooterDropdownContent | Ok |  
RecordTableColumnFooterWithDropdown | Ok |  
useOpenRecordFilterChipFromTableHeader | Ok |  
useCloseAnyOpenDropdown | Ok |  
useCloseDropdownFromOutside | Removed | Removed because unused
useDropdownV2 | Removed | Removed because all calls have been removed
useOpenDropdownFromOutside | Removed | Removed because unused
useCloseAndResetViewPicker | Ok |  
WorkflowVariablesDropdown | Ok |
2025-06-25 17:16:56 +02:00
WeikoandGitHub 74f53cc759 Fix array field migration (#12874)
Fixes https://github.com/twentyhq/twenty/issues/12726

## Context
Regression introduced in https://github.com/twentyhq/twenty/pull/12639
We now run raw queries for some migrations (column creations for
example) and we created a `typeormBuildCreateColumnSql` util for that.
The issue is that previously we were using typeorm methods which was
using isArray from the input to create $type[] (text[], number[])
properly which was not done in the new `typeormBuildCreateColumnSql`
util (so the type was text, number, etc...)
Edit: actually this was correctly implemented for Enum types (multi
select fields) but not Array type, I've updated the code accordingly
2025-06-25 16:42:07 +02:00
048075f5e3 i18n - translations (#12877)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-25 16:20:52 +02:00
nitinandGitHub 8056a5abc3 permissions - fix cancel button in create mode (#12870)
before - 


https://github.com/user-attachments/assets/9cbdc57d-40d6-42e3-ad5c-827a6602fbb5

after - 



https://github.com/user-attachments/assets/76e854eb-d809-4156-a386-b95c62461031
2025-06-25 16:09:22 +02:00
e2febbccea onboarding - signout button on Choose your workspaces modal (#12794)
@AMoreaux changes - 
- Added secondary background color to `StyledWorkspaceContainer`.
- Updated border styles for child elements to handle bottom borders
correctly.
- Removed redundant border styling from `StyledWorkspaceItem`.
Fix #12859 

my changes - 
- Add a logout button on the `Choose your Workspace` modal
- Remove the footer from the `Choose your Workspace` modal

---------

Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
2025-06-25 16:06:56 +02:00
Raphaël BosiandGitHub 1ab51d41aa Replace hotkey scopes by focus stack (Part 2 - Record Table, Rows and Cells) (#12798)
# Replace hotkey scopes by focus stack (Part 2 - Record Table, Rows and
Cells)

This PR is the second part of a refactoring aiming to deprecate the
hotkey scopes api in favor of the new focus stack api which is more
robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673

The record table shortcuts are no longer centralized in the record
table, they now split and the focused element is in charge of applying
the desired shortcuts. (For instance: The rows are in charge of the row
navigation and the cells of the cells navigation).

## Video QA:


https://github.com/user-attachments/assets/f0bb9eed-8a2a-4b6d-a82f-1998e929f122


## Bugfixes:

### Fix record table click outside not working after opening and closing
a cell

Introduced by https://github.com/twentyhq/twenty/pull/11644

#### Before


https://github.com/user-attachments/assets/d28deda8-15e9-4ffe-b60a-e8b54625f8e5


#### After


https://github.com/user-attachments/assets/3f7e1ffc-15d9-4336-aeb0-bebd8ae0cbe0


### Fix ObjectFilterDropdownFilterInput hotkeys

Introduced by https://github.com/twentyhq/twenty/pull/12673

#### Before


https://github.com/user-attachments/assets/ab2039bd-ebe1-49ba-8377-a6b300664469


#### After


https://github.com/user-attachments/assets/90597453-dab2-426b-a134-0a24b0de0a6b
2025-06-25 13:18:51 +00:00
Raphaël BosiandGitHub 6450e11f1e Fix page change effect being rerun after changes on views (#12869)
`useDefaultHomePagePath` was rerendered each time a view was changed, so
the PageChangeEffect reran every time a view was updated, but we only
want this effect to run on page change.
2025-06-25 13:09:00 +00:00
Paul RastoinandGitHub 0f106ab8e0 Field metadata relation edge cases exceptions coverage (#12866)
# Introduction
Following https://github.com/twentyhq/twenty/pull/12852

Discovered that:
- `relationCreationPayload` does not seem to be validated through the
input decorators
```ts
  // TODO @prastoin implement validation for this with validate nested and dedicated class instance
  @IsOptional()
  @Field(() => GraphQLJSON, { nullable: true })
  relationCreationPayload?: {
    targetObjectMetadataId: string;
    targetFieldLabel: string;
    targetFieldIcon: string;
    type: RelationType;
  };
```
- Sending an unknown `targetObjectMetadataId` generates an
`internal_server_error` `500` @guillim on the go
## Coverage
```ts
 PASS  test/integration/metadata/suites/object-metadata/failing-field-metadata-relation-creation.integration-spec.ts
  Field metadata relation creation should fail
    ✓ relation when targetFieldLabel is empty (109 ms)
    ✓ relation when targetFieldLabel exceeds maximum length (100 ms)
    ✓ relation when targetObjectMetadataId is unknown (97 ms)
    ✓ relation when targetFieldLabel contains only whitespace (103 ms)
    ✓ relation when targetFieldLabel conflicts with an existing field on target object metadata id (108 ms)

Test Suites: 1 passed, 1 total
Tests:       5 passed, 5 total
Snapshots:   5 passed, 5 total
Time:        2.629 s, estimated 3 s
```
2025-06-25 15:03:14 +02:00
GuillimandGitHub 8d3084ef16 fixing images url to main branch (#12862)
Simple fix for the readme on github
2025-06-25 10:47:39 +02:00
378e7cf6f1 change log, user guide, and readme updates for v1 launch (#12860)
### Summary 
- Minor updates to the user guide with clarification on product
functionality as per user confusion
- Updates to existing documentation about past features to reflect
current functionality (favorites, side panel controls, etc)
- Updated README with product hunt banner and new features for v1
release

---------

Co-authored-by: Vicky Wang <vw92@cornell.edu>
2025-06-25 10:19:04 +02:00
Paul RastoinandGitHub 3595c650a2 docs: upgrade guide (#12857) 2025-06-24 23:58:11 +02:00
Charles BochetandGitHub 95993dcdf0 Prevent index updates during sync metadata (#12856)
As per title
2025-06-24 22:10:36 +02:00
fb0cf11499 check on label metadata (#12852)
Better catching label input

- there were absolutely no check on label when creating the target field
while doing a relation : we crearted these checks here.

- We keep the label quite open to special char as discussed with Felix.
so mostly checking length of label.
  - We check that label does not already exists on the targetted object


- making sure the Target fieldinput label is checked before we create
it. The previous checks are not enough since the label goes through
anoteher merthod before going in the database

- validate-metadata-name-is-camel-case.utils.ts : making sure we can use
this error message for metadata name and for target label

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: prastoin <paul@twenty.com>
2025-06-24 20:20:37 +02:00
Paul RastoinandGitHub 02ce53bd2f 1.0.0 commands (#12853) 2025-06-24 20:20:15 +02:00
Paul RastoinandGitHub 2fc300a63c Remove number from label identifier list (#12831) 2025-06-24 18:05:27 +00:00
b31845b7ba Fix resolver-validation validation snake trap (#12850)
# Introduction
This PR might have a lot of impact on tested validation
Avoid catching programmatically thrown error

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-24 18:30:56 +02:00
Antoine MoreauxandGitHub b7e72c3aa6 feat(captcha): improve telemetry on captcha error (#12836) 2025-06-24 17:43:03 +02:00
WeikoandGitHub 3cef6c9048 Force readonly for deletedAt field (#12840)
Fixes https://github.com/twentyhq/twenty/issues/12839

## Context
We now force readonly mode for deletedAt datepicker as permissions don't
handle well this use case. The frontend should call softDelete endpoint
in this case. For a user, they should select the record and click on the
trash icon instead

<img width="467" alt="Screenshot 2025-06-24 at 17 30 03"
src="https://github.com/user-attachments/assets/0a8a0709-305b-440f-91c2-d5e3f23ca213"
/>
2025-06-24 17:34:17 +02:00
nitinandGitHub d7c6806ad4 fix confirmation modal on subdomain settings (#12845)
before - 


https://github.com/user-attachments/assets/ff063912-0c1e-41e4-b01d-15081ecb04a1

after - 



https://github.com/user-attachments/assets/0ee6022d-f0a8-4243-a108-c4295d0fb560
2025-06-24 17:34:03 +02:00
Charles BochetandGitHub 77f0ed2208 Fix recordTableCells being displayed several time on record group tables (#12843)
As per title!
2025-06-24 17:29:50 +02:00
Baptiste DevessierandGitHub baaec81a91 Use default color in Loader component for CSS variable (#12844)
Fixes a regression introduced by
https://github.com/twentyhq/twenty/pull/11639

cc @AMoreaux 

## Before

![CleanShot 2025-06-24 at 17 20
21@2x](https://github.com/user-attachments/assets/8360da38-98b7-42a0-91b8-15caa5dde802)

## After

![CleanShot 2025-06-24 at 17 18
21@2x](https://github.com/user-attachments/assets/9953ec11-f22c-49ea-9023-fe42e79761b5)



https://github.com/user-attachments/assets/875c6c7e-3fc3-44bf-bb17-69ca362c1145
2025-06-24 17:29:36 +02:00
Antoine MoreauxandGitHub f5c179a8bf Fix bug on sso providers (#12841) 2025-06-24 17:27:32 +02:00
EtienneandGitHub 09c1162ddd fix phones in prefill (#12838)
Context : wrong format, import of pre-filled people is not working for
example
2025-06-24 17:22:48 +02:00
WeikoandGitHub ed11cac5f7 Add graphql queries error codes metrics (#12833)
## Context
Added to the existing useGraphQLErrorHandlerHook yoga hook to increment
metrics after all query executions based on their error codes. I
originally wanted to create a new useMetrics hook but most of the error
handling was done in useGraphQLErrorHandlerHook so we decided to keep it
there for now.

<img width="1310" alt="Screenshot 2025-06-24 at 15 58 26"
src="https://github.com/user-attachments/assets/498d3754-851a-4051-a5c2-23ac8253aa6a"
/>
2025-06-24 16:13:33 +02:00
Charles BochetandGitHub b8fd10e9e8 Add logging for recaptcha token (#12834) 2025-06-24 16:12:39 +02:00
EtienneandGitHub 08f8302148 Import - add duplicate check on import (#12810)
<img width="1217" alt="Screenshot 2025-06-24 at 11 43 03"
src="https://github.com/user-attachments/assets/de2bc12e-5e25-484f-a034-f52b0f237a3e"
/>

Test : 
- Add duplicate on id or on primaryEmail for people or primaryUrlLink on
companies

closes https://github.com/twentyhq/core-team-issues/issues/909
2025-06-24 16:12:20 +02:00
EtienneandGitHub cc489f971d fix type (#12832) 2025-06-24 15:58:28 +02:00
GuillimandGitHub 7a9ec55c5c switch datasourcing (#12825)
This PR improves error handling in `handleDriverException` by adding a
duck-typing check for `MessageImportDriverException` objects. It ensures
that errors are correctly identified and processed even if they are
received as plain objects rather than class instances. This change
prevents missed exception handling and increases the robustness of the
message import process.
2025-06-24 15:32:16 +02:00
Thomas TrompetteandGitHub b063510c79 Add metrics to workflows (#12829)
- ensure each trigger is working properly
- check throttle does not happen too often
- keep an eye on the completed/failed proportion
2025-06-24 15:31:47 +02:00
martmullandGitHub ce55b20faa Use main dataSource to query CRON jobs (#12830)
As title
2025-06-24 13:29:00 +00:00
251a19b87d i18n - translations (#12828)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-24 15:15:50 +02:00
8cf7649a4c Add object level form to role creation (#12826)
## Context
- Add object-level form to role creation
- Add isSaving props for save button isLoading state
<img width="594" alt="Screenshot 2025-06-24 at 15 03 59"
src="https://github.com/user-attachments/assets/77d9d399-4e1a-4e35-be45-c19100ef06c1"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-24 15:15:37 +02:00
MarieandGitHub 540f3ffd67 Fix phone deletion (#12821)
Fixes https://github.com/twentyhq/core-team-issues/issues/1124
2025-06-24 13:12:40 +00:00
Charles BochetandGitHub 2da66af26a Improve onboarding experience (#12824)
https://github.com/user-attachments/assets/365c1618-e9d5-46d5-9b54-bed2cdeb7c02
2025-06-24 15:06:50 +02:00
Félix MalfaitandGitHub 21f9db1f41 Improve breaking change CI (#12816)
It used to post a comment if the API schema changed, even if there's no
breaking change. I thought this could be OK as an FYI. But it is not
since now we generate the examples dynamically with Faker the OpenAPI
schema is always different
2025-06-24 14:53:14 +02:00
GuillimandGitHub 95decc6401 additionaldata-message-exception (#12819)
better loging exceptions by keeping the orginal error (otherwise it's
swallowed and hard to debug precisely)
2025-06-24 14:52:03 +02:00
b4f7b547f1 i18n - translations (#12820)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-24 14:43:14 +02:00
480f135282 i18n - translations (#12818)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-24 14:22:44 +02:00
WeikoandGitHub 6f1107eecd Revert "[Permissions] Force open title input for role label when empty" (#12817)
Reverts twentyhq/twenty#12710
2025-06-24 14:08:16 +02:00
WeikoandGitHub 074cd22a67 [Permissions] Force open title input for role label when empty (#12710)
- Fix empty title in breadcrumb 
- Enforce role label input open if empty
2025-06-24 14:06:50 +02:00
Charles BochetandGitHub 4ac208cf1c Query dynamic cache key computation (#12814)
In this PR:
- add query hashKey to ObjectMetadataItems query graphql cache to avoid
caching outdated queries
- improve performance by removing ResolveField at FieldLevel and adding
this at resolver level
2025-06-24 12:04:00 +00:00
Lucas BordeauandGitHub 48347095d2 Fixed ACTOR advanced filter recent regressions (#12813)
This PR fixes recent regressions on advanced filters for the ACTOR field
type.

- The new `isFilterable` props on
`SETTINGS_COMPOSITE_FIELD_TYPE_CONFIGS` wasn't taken into account for
sub field picker in advanced filter.
- A wrong component instance id was passed to
`subFieldNameUsedInDropdownComponentState`
2025-06-24 13:57:18 +02:00
Lucas BordeauandGitHub 81d70e6fa3 Fixed relative date filter initalization (#12811)
This PR fixes problems with date filter : 
- Filter chip shows the label with plural, ex : `This weeks` 
- Using a relative filter now initializes to `This day`
- Switching between the different relative sub-operands (This, Past,
Next) now initializes with a value so we're never in an "empty" state.
2025-06-24 13:57:05 +02:00
GuillimandGitHub 5c3550a2ee in connected account, refresh-token can fail with network error (#12815)
This PR fixes this issue from the connected account refresh token
service that is

This PR fixes error handling in `handleDriverException` by ensuring that
errors resembling `MessageImportDriverException` are correctly detected,
even if they are plain objects and not true class instances. This
prevents missed exception handling due to failed `instanceof` checks.

Was introduced by [this
PR](https://github.com/twentyhq/twenty/pull/12233) that did not know all
provider cases that can occur.

Fixes https://github.com/twentyhq/twenty/issues/12589
2025-06-24 13:51:03 +02:00
3cee2b796f Fixed record picker loading flickering (#12736)
This PR solves a flickering effect on record pickers on the different
loading state they can be in.

It was designed with @Bonapara to settle on a nice UX feeling.

## Before

With fast network (local) :


https://github.com/user-attachments/assets/58899934-c705-4b44-b7f6-289045032c11

With slow network : 


https://github.com/user-attachments/assets/9fb18d86-9da6-4e5d-a83f-00c810fab2dc

## After


https://github.com/user-attachments/assets/f4abb40f-5d42-4c46-88ab-aaef4f883f7f

Fixes https://github.com/twentyhq/twenty/issues/12680

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-24 12:15:50 +02:00
Antoine MoreauxandGitHub 9aaa104ec0 feat(infra-dev): add opentelemetry and grafana (#12808) 2025-06-24 12:13:24 +02:00
Lucas BordeauandGitHub c56ccf7ed9 Fixes date filter chip bugs (#12788)
This PR fixes a bug that occurs during filter operand changes.

As a date filter can contain values that have a different shape, mainly
date ISO string and hard-coded relative dates, changing the operand
without resetting the value to its default was causing a crash.

This PR also extracts the logic that computes the right part of a filter
chip into a util instead of a difficult to understand ternary, thus
solving small bugs in the value displayed also.

Fixes https://github.com/twentyhq/twenty/issues/12778
2025-06-24 09:29:28 +00:00
84b204dcab i18n - translations (#12809)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-24 10:38:44 +02:00
d0126e22ee feat: ability to switch currency format (#12542)
Fixes #11927

I have added 'format' in the zod schema of currency, and for using it, I
am separately passing 'format' to 'currencyDisplay.'
The feature is working correctly.

---------

Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
2025-06-24 10:28:50 +02:00
6651abae18 i18n - translations (#12807)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-23 23:33:18 +02:00
Charles BochetandGitHub d8f4e7e233 Add loader on workspace creation (#12806)
Not my most brillant design but it should work!
                  


https://github.com/user-attachments/assets/b89ae6d8-84ca-43c4-a010-d0686d522183
2025-06-23 23:23:13 +02:00
4eb859256c feat(settings): add loading state to save buttons (#11639)
Introduce a loading state to SaveButton and SaveAndCancelButtons
components to enhance user feedback during save operations. Update
SettingsNewObject to manage the loading state while submitting the form.

Fix https://github.com/twentyhq/core-team-issues/issues/572

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-23 22:49:38 +02:00
WeikoandGitHub d248e536f3 Fix CombinedFindManyRecords with permissions (#12805)
## Context
This was already for relations but not the root object. This caused
issues with pages where we query multiple objects with the
CombinedFindManyRecords such as the data model

In the example below, we don't have access to rockets so we don't see
the real number of instances (now displays 0) and the FE shouldn't query
it.
<img width="557" alt="Screenshot 2025-06-23 at 19 23 51"
src="https://github.com/user-attachments/assets/2ee769b6-c108-466e-93ef-a17a6b092fcc"
/>

Diff
<img width="1232" alt="Screenshot 2025-06-23 at 19 39 05"
src="https://github.com/user-attachments/assets/6c841d4f-2a64-4908-8423-dc040893dfac"
/>
<img width="1224" alt="Screenshot 2025-06-23 at 19 38 57"
src="https://github.com/user-attachments/assets/bb3ff3bc-e9e4-40a6-b72f-18b4dc109df9"
/>
2025-06-23 21:27:58 +02:00
Charles BochetandGitHub d5c974054d Improve performance on metadata computation (#12785)
In this PR:

## Improve recompute metadata cache performance. We are aiming for
~100ms

Deleting relationMetadata table and FKs pointing on it
Fetching indexMetadata and indexFieldMetadata in a separate query as
typeorm is suboptimizing

## Remove caching lock

As recomputing the metadata cache is lighter, we try to stop preventing
multiple concurrent computations. This also simplifies interfaces

## Introduce self recovery mecanisms to recompute cache automatically if
corrupted

Aka getFreshObjectMetadataMaps

## custom object resolver performance improvement:  1sec to 200ms

Double check queries and indexes used while creating a custom object
Remove the queries to db to use the cached objectMetadataMap

## reduce objectMetadataMaps to 500kb
<img width="222" alt="image"
src="https://github.com/user-attachments/assets/2370dc80-49b6-4b63-8d5e-30c5ebdaa062"
/>

We used to stored 3 fieldMetadataMaps (byId, byName, byJoinColumnName).
While this is great for devXP, this is not great for performances.
Using the same mecanisme as for objectMetadataMap: we only keep byIdMap
and introduce two otherMaps to idByName, idByJoinColumnName to make the
bridge

## Add dataloader on IndexMetadata (aka indexMetadataList in the API)

## Improve field resolver performances too

## Deprecate ClientConfig
2025-06-23 21:06:17 +02:00
nitinandGitHub 6aee42ab22 register all cron jobs in entrypoint (#12791)
closes https://github.com/twentyhq/core-team-issues/issues/1113

Three things I am not sure about - 
- Should we have a variable just like DISABLE_DB_MIGRATIONS to control
cron job registration behavior, i.e., DISABLE_CRON_JOBS_REGISTRATION?
- The location of the command ie, folder placement
- https://github.com/twentyhq/twenty/pull/12791/files#r2161734131
2025-06-23 21:05:01 +02:00
MarieandGitHub 00eb93463c [permissions V2] Fix - filter objects to search (#12803)
In morph relation pickers, we were not taking into account permissions
when computing the list of objects to search for, while we should not
search for objects we don't have read permissions on (permission denied
error)
2025-06-23 19:35:08 +02:00
37b48e2b21 i18n - translations (#12804)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-23 19:20:12 +02:00
WeikoandGitHub 85c50f149d [Permissions][FE] Design followup 5 (#12793)
## Context
- We now display workspace member full name and email in role assignment
picker
- Replaced Forbidden by "Not shared" with lock icon
- Fix Disabled for Danger accent
- Fix avatar URL

<img width="575" alt="Screenshot 2025-06-23 at 16 38 56"
src="https://github.com/user-attachments/assets/08430bfe-29c4-4ac4-821c-9062dfad7150"
/>
<img width="756" alt="Screenshot 2025-06-23 at 16 21 36"
src="https://github.com/user-attachments/assets/c19f31bd-fe9d-415d-aa55-62fa3e228c49"
/>
<img width="373" alt="Screenshot 2025-06-23 at 17 13 08"
src="https://github.com/user-attachments/assets/e2f7878c-7c5a-40b4-a482-8e99292257c3"
/>
<img width="342" alt="Screenshot 2025-06-23 at 17 37 49"
src="https://github.com/user-attachments/assets/04169e85-14dd-4aed-bd71-7aefd601a894"
/>
<img width="434" alt="Screenshot 2025-06-23 at 17 37 35"
src="https://github.com/user-attachments/assets/7caf0967-c4dd-4d0f-90c8-259a85182b19"
/>
2025-06-23 19:15:58 +02:00
Thomas TrompetteandGitHub f05da75bb5 Set error message not absolute (#12802)
Before
<img width="485" alt="Capture d’écran 2025-06-23 à 18 52 50"
src="https://github.com/user-attachments/assets/19c60cd1-f241-4419-9d03-d16d019f2c04"
/>

After
<img width="485" alt="Capture d’écran 2025-06-23 à 18 48 01"
src="https://github.com/user-attachments/assets/85b68984-11e0-456b-aacb-5a0661818b9c"
/>
<img width="485" alt="Capture d’écran 2025-06-23 à 18 48 38"
src="https://github.com/user-attachments/assets/7380d537-e8d0-411c-b4f8-7b38b6550e20"
/>
2025-06-23 17:08:40 +00:00
MarieandGitHub 7ff2f32438 Add position / positions to reserved keywords (#12800) 2025-06-23 19:02:02 +02:00
GuillimandGitHub 26d8498a4a [Messaging logs] Better logging AggregateError (#12801)
"An AggregateError in NestJS usually indicates that multiple errors were
thrown or collected together and then re-thrown as a single error."

Since we have this in logs, we cannot debug properly the error
https://github.com/twentyhq/twenty/issues/12589
<img width="911" alt="Screenshot 2025-06-23 at 18 39 16"
src="https://github.com/user-attachments/assets/888d620f-8d1a-4b59-93b6-2d716a4ab77c"
/>

That is why we will better log this errors in order to tackle them ASAP

Note: sentry errors match our Grafan logs agggregate errors as you can
see

<img width="298" alt="Screenshot 2025-06-23 at 18 39 58"
src="https://github.com/user-attachments/assets/fc412153-4f91-4eea-a9db-8e72c67f8ffc"
/>
<img width="973" alt="Screenshot 2025-06-23 at 18 40 46"
src="https://github.com/user-attachments/assets/2bf01947-bb6e-4f48-b94b-777acfd83012"
/>
2025-06-23 16:53:11 +00:00
Thomas TrompetteandGitHub 981cbb4257 Generate id for standard multi select field options (#12799)
Fixes https://github.com/twentyhq/twenty/issues/12723

After


https://github.com/user-attachments/assets/1f957dda-d2d0-434f-a4cd-f37c759e9f46
2025-06-23 18:49:51 +02:00
martmullandGitHub 6e4dc16f2b 12660 bugapi create one person post api request example is returning 400 in playground (#12787)
Use faker to provide simple working examples for REST API create one,
create many, update one and find duplicates

Eg:
<img width="1505" alt="image"
src="https://github.com/user-attachments/assets/99be990f-efd6-4ad7-8c29-f9dcecac112f"
/>
2025-06-23 18:24:42 +02:00
Thomas TrompetteandGitHub 06fddc2ae0 Remove ID field + fix relations + remove runs (#12796)
- id field should only be available for search records action
- create record action does not work for relations. Requires to send
`accountOwner: { id: string }` instead of `accountOwner: string`
- hidding `runs` for version views as we did for workflows
2025-06-23 18:03:11 +02:00
Baptiste DevessierandGitHub d99bff983e Fix styling inconsistency for FormSingleRecordFieldChip placeholder (#12795)
## Before

![CleanShot 2025-06-23 at 17 01
16@2x](https://github.com/user-attachments/assets/8fb40b91-a17a-48dc-8d5e-6657bdcf8434)



## After


![CleanShot 2025-06-23 at 17 01
01@2x](https://github.com/user-attachments/assets/a9781e13-200c-4aa2-9907-a0c8f4a1dd67)
2025-06-23 17:32:51 +02:00
MarieandGitHub 4c94fc2803 [permissions V2] Remove feature flag (#12790) 2025-06-23 15:22:57 +00:00
Paul RastoinandGitHub b6787c6fcd Record filter greaterThan becomes inclusive as lowerThan (#12786)
# Introduction
Greater than filtering wasn't inclusive whereas lower than was,
resulting in sending empty array to filtering resolver

Also refactored the transpilation methods to avoid asserting on the
`RATING_VALUES` order

closes https://github.com/twentyhq/twenty/issues/12779
2025-06-23 15:15:30 +00:00
EtienneandGitHub facd2fe26f Import - fix import with multiple unique constraints (#12784)
Test : 
- For company for example, in import, update of domainName works (Export
companies, import them updating domainName.primaryLink)
2025-06-23 15:10:41 +00:00
Paul RastoinandGitHub b2a560e08d Fix rating field default value (#12792)
close https://github.com/twentyhq/twenty/issues/12789
2025-06-23 16:56:09 +02:00
Félix MalfaitandGitHub 2e296e775e Fix export to pdf (#12782)
Export to PDF was throwing an error due to fonts not being registered.
Maybe linked to the async loading changes or blocknote upgrades.


I wasn't a fan of hardcoding the fonts here (makes a second source of
truth for Inter), but after a few tests this seemed like the best
compromise
2025-06-23 16:27:21 +02:00
2cb2f528df [permissions - seeds] Give tim@apple.dev restricted rights (#12768)
Let's introduce an object-limited role for Tim, to test and/or spot
incompatibilities with restricted permissions in the future.
Our main user tim@apple.dev is now assigned a role that has all settings
permissions, and all object permissions except for update on Pets (to
test read-only view) and read on Rockets.
Since we still need an admin user for each workspace we are introducing
a new member, Jane, who has the admin role

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-06-23 13:46:53 +00:00
Baptiste DevessierandGitHub 8f0c9facf2 Fix e2e tests (#12783)
Fixes:

- Trigger labels have been updated in the workflows
- Workflow runs are now opened by default in the side panel when
launched manually by the user
2025-06-23 13:34:35 +02:00
nitinandGitHub bec4a98ae7 add firstname and lastname on current user state and sync it while cr… (#12781)
…eating profile and pass it to cal.com's embed
2025-06-23 15:25:35 +05:30
Charles BochetandGitHub b76dac2ca1 BREAKING CHANGE: Fix graphql errors (#12775)
We were using a global ValidationPipe in main.ts. This is an issue as
@Controllers should return HttpExecption and @Resolvers should return
GraphqlErrors

Removing the global pipe and creating a ResolverValidationPipe able to
generate GraphqlError. We also need to handle the exception in a filter
to avoid nest to think it's unhandled and make it flow to logs


Next step:
- it would be nice to have both @UsePipes(ResolverValidationPipe) +
@UseFilters(GraphqlValidationExceptionFilter) come together. This should
be possible if we create a @GraphQLResolver annotation
2025-06-23 11:23:16 +02:00
8e30da99e9 i18n - translations (#12777)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-22 22:01:09 +02:00
+19 65df511179 feat: Add AI Agent workflow action node (#12650)
https://github.com/user-attachments/assets/8593e488-cb00-4fd2-b903-5ba5766e0254

---------

Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
Co-authored-by: Joseph Chiang <josephj6802@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
Co-authored-by: Naifer <161821705+omarNaifer12@users.noreply.github.com>
Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: Ajay A Adsule <103304466+AjayAdsule@users.noreply.github.com>
Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Marty <91310557+real-marty@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
2025-06-22 21:42:04 +02:00
Baptiste DevessierandGitHub 22e126869c Allow json in workflow run's error field (#12762)
We can now inspect errors even if they contain complex data as objects.
Only the first line of the error is put in red.



![CleanShot 2025-06-20 at 18 31
54@2x](https://github.com/user-attachments/assets/a3fd41fb-0063-4fe1-8185-54137c2a0d6e)


![image](https://github.com/user-attachments/assets/833a2851-e7d5-4985-9e42-07a1899cd3de)
2025-06-20 19:07:24 +02:00
Baptiste DevessierandGitHub 1e0ee9421d Hide tab system for pending form nodes (#12769)
| | Before | After |
|--------|--------|--------|
| **Pending form** | ![CleanShot 2025-06-20 at 15 49
03@2x](https://github.com/user-attachments/assets/6cfac5d2-3db2-4dfa-844e-68bf2432c7ba)
| ![CleanShot 2025-06-20 at 15 41
01@2x](https://github.com/user-attachments/assets/720cbcb1-8468-418a-a2c0-09b00da76592)
|
| **Completed form** | ![CleanShot 2025-06-20 at 15 41
18@2x](https://github.com/user-attachments/assets/12b18de0-efe4-45d2-af2e-fc48d6911225)
| ![CleanShot 2025-06-20 at 15 49
13@2x](https://github.com/user-attachments/assets/0e35708e-a933-4127-8d61-d5d7f6c85802)
|
2025-06-20 18:35:25 +02:00
EtienneandGitHub 830e49c5b1 Onboarding - delete PENDING_CREATION workspace if billing is deactivated (#12704)
[More context
details](https://discord.com/channels/1130383047699738754/1384834012882927637/1384834143673778226)
2025-06-20 18:18:50 +02:00
Paul RastoinandGitHub e11bd7aa0f getLabelIdentifierFieldValue should always return string (#12772)
## Introduction

For a custom object if the selected identifier field metadata is an
number type than it wouldn't get be converted to a string

#closes https://github.com/twentyhq/twenty/issues/12717

## Concerns
Kinda the same than for https://github.com/twentyhq/twenty/pull/12728

Here ObjectRecord unknown fields are typed as any, we might wanna do a
poc in order to migrate to `unknown` usage
```ts
import { BaseObjectRecord } from '@/object-record/types/BaseObjectRecord';

export type ObjectRecord = Record<string, any> & BaseObjectRecord;
```
2025-06-20 17:58:31 +02:00
Charles BochetandGitHub 94557e7447 Fix attachment body not being loaded (#12770)
Closes https://github.com/twentyhq/twenty/issues/12756
2025-06-20 17:50:49 +02:00
Thomas TrompetteandGitHub a8ff02efc3 Gap fixes on search record (#12766)
As title

See :
https://discord.com/channels/1130383047699738754/1385199391580885012
https://discord.com/channels/1130383047699738754/1385198545312809083
2025-06-20 16:02:56 +02:00
1bdc03f4a4 i18n - translations (#12767)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-20 15:38:51 +02:00
Félix MalfaitandGitHub ea226f9e71 Fix flaky calendar test (#12760)
Test was flaky because sometimes a calendar event is associated to an
account which the user does not have access to

Removing the snapshot to test the exact response value but the test is
still there (more flexible)
2025-06-20 15:30:42 +02:00
EtienneandGitHub 19fe508ec3 fix confirm close dialog + add restart confirm dialog (#12761)
Test: 
- On upload > No dialog at modal closing
- On match > Confirm cancel dialog at closing (escape, click outside,
cancel cross)
- On match > Restart dialog at Restart Import
- On validation > Confirm cancel dialog at closing (escape, click
outside, cancel cross)
- On import > Confirm cancel dialog at closing (escape, click outside,
cancel cross)
- On import > No confirm at import end

closes : https://github.com/twentyhq/core-team-issues/issues/1071
2025-06-20 15:20:17 +02:00
Paul RastoinandGitHub 0e669e621d Upgrade guide cache flush for 0.55 user permissions not found (#12765)
Related to https://github.com/twentyhq/twenty/issues/12651
2025-06-20 14:47:04 +02:00
Charles BochetandGitHub 24fa479cbf Fix webhook size too big (#12749) 2025-06-20 14:42:25 +02:00
GuillimandGitHub 3977506796 temporary code (#12757)
In order to put back relations on track, we need to allow the
preexisting indexes to be created in indexmetadata, but also to avoid
failure when the migration runner will try to re-apply a pre-existing
index
2025-06-20 14:20:16 +02:00
6820401c93 i18n - translations (#12764)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-20 14:01:31 +02:00
WeikoandGitHub 7687f4f285 [permissions][FE] followup design fixes 4 (#12737)
## Context
- Whole row is now clickable
- Fix padding on role tables
- Fix tab being persistant between roles
- Change various texts/descriptions
- Add un/check all on settings permissions
- Fix flash between role detail and roles
- Add "Granted for X object(s)"
- Swap permissions and assignment tabs position
- add tooltip for object level permission actions
- Add the inherited info on object-level permissions
2025-06-20 11:53:19 +00:00
Antoine MoreauxandGitHub 57abc246ef fix(auth): social login (#12759)
Fix https://github.com/twentyhq/private-issues/issues/280
2025-06-20 10:01:23 +00:00
Antoine MoreauxandGitHub 5b81e9e611 fix(auth): handle availableWorkspacesCount correctly when listing wor… (#12746)
…kspaces
2025-06-20 11:55:02 +02:00
Antoine MoreauxandGitHub 2469c509a6 fix(auth): add captcha auto-refresh via ApolloLink (#12758)
- Introduced `createCaptchaRefreshLink` to trigger captcha token refresh
automatically.
- Removed redundant manual captcha refresh calls and integrated it into
Apollo Provider.
2025-06-20 11:38:01 +02:00
Paul RastoinandGitHub fe5574fdf6 UpdateServerless migration fix 2 (#12755)
closes
https://github.com/twentyhq/twenty/issues/12651#issuecomment-2990255291
2025-06-20 09:35:27 +00:00
EtienneandGitHub 901cc1feb8 OTLP Metrics - update to delta aggregation (#12752)
Source :
https://opentelemetry.io/docs/specs/otel/metrics/data-model/#sums
2025-06-20 08:03:50 +00:00
Félix MalfaitGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
cb6a76fd43 Improve seeds 3 (#12740)
- Fix an issue where custom object were seeded with 2 views, and with
the wrong icon
- ACME becomes YCombinator
- Allow 2 workspaces to have different metadata seeded
- Add many seeds for messages
- Add many seeds for calendar events
- Randomize createdBy for person and companies

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-06-20 07:05:44 +02:00
Baptiste DevessierandGitHub 79e5ccfd37 Set viewport when nodes dimensions are ready (#12730)
Sometimes, we try to set the viewport, but the nodes' dimensions have
been reset. Trying to set the viewport when the nodes' dimensions are
incorrect leads to an incorrect viewport.

This PR ensures we only try to set the viewport if the nodes' dimensions
are valid. Otherwise, we wait for them to be computed to set the
viewport automatically.

The `handleNodesChanges` function is called every time the nodes change,
including when the dimensions have been computed.

Internally, Reactflow has a similar behavior to implement the `fitView`
feature:
https://github.com/xyflow/xyflow/blob/f9971a8fad54e9c2f33b71b4056b6d1ec6c33bd1/packages/react/src/store/index.ts#L111.

## Example

This is more notable since I added optimistic rendering to workflow
runs.


https://github.com/user-attachments/assets/07232050-b808-4345-b82b-95acad72ab15
2025-06-19 18:47:36 +02:00
58e1e69280 i18n - translations (#12747)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-19 18:37:49 +02:00
martmullandGitHub 28466ecbf3 Add icon select to manual trigger (#12724)
## After

<img width="1220" alt="image"
src="https://github.com/user-attachments/assets/98a73aae-80d7-4e92-93d3-be13210da88b"
/>

<img width="1131" alt="image"
src="https://github.com/user-attachments/assets/9919e415-4355-4995-8979-9055b821f1e9"
/>

<img width="1300" alt="image"
src="https://github.com/user-attachments/assets/27f11cb3-d72c-468a-a641-8414172b9b54"
/>

<img width="1353" alt="image"
src="https://github.com/user-attachments/assets/2f0037f2-fe17-48b6-b7e6-c7528687a5fd"
/>
2025-06-19 16:32:42 +00:00
MarieandGitHub adcf6107e7 Revert "fix(signinup): several issues (#12698)" (#12745)
This reverts commit 9612a4928d.

(Causes a google auth sign-up issue)
2025-06-19 18:15:15 +02:00
martmullandGitHub b778b6ebad Remove url checking in workflow run (#12743)
## Before

<img width="1064" alt="image"
src="https://github.com/user-attachments/assets/4f9081d7-1e2d-438b-b7ac-8537c1f3a676"
/>

## After

<img width="1062" alt="image"
src="https://github.com/user-attachments/assets/2463f21c-f0e9-4c8c-b91e-55181bad8799"
/>
2025-06-19 18:01:37 +02:00
Thomas TrompetteandGitHub 2d6d5bf7d6 Prevent workflows to be opened in side panel (#12738)
Workflow views and versions are seed being opened by default into record
page. Issue is that:
- new views are set by default to side panel. Updated by copying the
current opensIn value to the new view
- users can still select side panel into their options. Disabling the
button.

<img width="650" alt="Capture d’écran 2025-06-19 à 16 15 34"
src="https://github.com/user-attachments/assets/0ddc3284-0fed-404f-9c1d-225c65549fd1"
/>
2025-06-19 15:09:56 +00:00
Paul RastoinandGitHub 5c118b91ac Protect serverless migration metadata operations interacting with metadata (#12739)
# Introduction

This migration has been introduced in 0.54 we should determine how we
wanna handle retro-compatibility with this, might not wanna merge this
one latest main 🤔 but only a new 0.54 patch

related to
https://github.com/twentyhq/twenty/issues/12651#issuecomment-2988164122

## Concerns
If a workspace fails this migration that's not a good sign, the metadata
schema should be completely empty since 0.54 `metadata` merge into
`core` migration.
Please review you existing entries in the schema and verify they exists
in the dest `core` one
2025-06-19 17:09:14 +02:00
6d56b75962 12690-error-unknown-error-importing-calendar-events-reafcto-required (#12711)
Why : we had an issue impoting events du to CalendarEvents not yet
existing while inserting the CalendarChannelAssociation due to inverted
method in the service

This PR refactors the calendar event import logic by 
- renaming 
- splitting utility functions for better clarity and maintainability. 
- adding TSDoc comments to explain the purpose and uniqueness of the
`eventExternalId` field in calendar event associations


Fixes #12690

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-19 15:04:21 +00:00
Paul RastoinandGitHub e1393c4887 Transform record phone field metadata (#12706)
# Introduction
close https://github.com/twentyhq/twenty/issues/12343

Adding a transform step for any field phone in order to infer country
code and calling code from the number if they're provided

## Edges cases
```ts
RecordTransformerExceptionCode.INVALID_PHONE_NUMBER:
RecordTransformerExceptionCode.INVALID_PHONE_COUNTRY_CODE:
RecordTransformerExceptionCode.CONFLICTING_PHONE_COUNTRY_CODE:
RecordTransformerExceptionCode.CONFLICTING_PHONE_CALLING_CODE:
RecordTransformerExceptionCode.CONFLICTING_PHONE_CALLING_CODE_AND_COUNTRY_CODE:
RecordTransformerExceptionCode.INVALID_PHONE_CALLING_CODE:
RecordTransformerExceptionCode.INVALID_URL:
```

## Coverage
Note: Will handle REST api integration testing pivot and UPDATE
operation later in the afternoon, critical bug appeared that I prefer
handling before improving this PR coverage, also would be too many
updates
Note2: Haven't fuzzed all of the string inputs, would seem overkill for
such a use case, to be debated
```ts
 PASS  test/integration/metadata/suites/field-metadata/phone/create-one-field-metadata-phone.integration-spec.ts (23.609 s)
  Phone field metadata tests suite
    ✓ It should succeed create primary phone field (1397 ms)
    ✓ It should succeed create primary phone field with number and other information (930 ms)
    ✓ It should succeed create primary phone field with full international format and other information (893 ms)
    ✓ It should succeed create primary phone field with full international and infer other information from it but not the countryCode as its shared (825 ms)
    ✓ It should succeed create primary phone field with full international and infer other information from it (818 ms)
    ✓ It should succeed create primary phone field with empty payload (827 ms)
    ✓ It should succeed create additional phone field with number and other information (894 ms)
    ✓ It should succeed create additional phone field with full international format and other information (1024 ms)
    ✓ It should succeed create additional phone field with full international and infer other information from it but not the countryCode as its shared (808 ms)
    ✓ It should succeed create additional phone field with full international and infer other information from it (751 ms)
    ✓ It should succeed create additional phone field with empty payload (739 ms)
    ✓ It should fail to create primary phone field without country or calling code at all (776 ms)
    ✓ It should fail to create primary phone field with invalid country code (782 ms)
    ✓ It should fail to create primary phone field with invalid calling code (858 ms)
    ✓ It should fail to create primary phone field with conflicting country code and calling code (872 ms)
    ✓ It should fail to create primary phone field with invalid phone number format (1489 ms)
    ✓ It should fail to create primary phone field with conflicting phone number country code (1425 ms)
    ✓ It should fail to create primary phone field with conflicting phone number calling code (1553 ms)
    ✓ It should fail to create primary phone field without country or calling code at all (814 ms)
    ✓ It should fail to create primary phone field with invalid country code (813 ms)
    ✓ It should fail to create primary phone field with invalid calling code (742 ms)
    ✓ It should fail to create primary phone field with conflicting country code and calling code (783 ms)
    ✓ It should fail to create primary phone field with invalid phone number format (731 ms)
    ✓ It should fail to create primary phone field with conflicting phone number country code (947 ms)
    ✓ It should fail to create primary phone field with conflicting phone number calling code (822 ms)

Test Suites: 1 passed, 1 total
Tests:       25 passed, 25 total
Snapshots:   14 passed, 14 total
Time:        23.627 s
```
2025-06-19 16:39:58 +02:00
Paul RastoinandGitHub 1d1718a8a8 0.60.0 upgrade commands (#12735)
# Introduction
Even tho there's no commands we need to add the `0.60.0` entry within
the records
2025-06-19 14:09:44 +00:00
Antoine MoreauxandGitHub c48b80dfa6 fix(): add loader on signup (#12714)
Fix #12713
2025-06-19 16:07:10 +02:00
Lucas BordeauandGitHub bb3008e12b Fixed record pickers create new (#12705)
This PR fixes many bugs related to creating a record from inside a
relation picker, single or multiple.

QA video : 

Part 1 :


https://github.com/user-attachments/assets/35450b08-ff84-4698-8318-681d72437cd4

Part 2 : 


https://github.com/user-attachments/assets/807c3a7b-4116-41ff-b9a0-23767452b631

Also : 

- Refactored `RecordDetailRelationSectionDropdown` to split it into two
components to avoid too many ternaries inside functions.

Fixes https://github.com/twentyhq/twenty/issues/12668
Fixes https://github.com/twentyhq/twenty/issues/12669
Fixes https://github.com/twentyhq/twenty/issues/12670
Fixes https://github.com/twentyhq/twenty/issues/12671
2025-06-19 13:37:21 +00:00
Thomas TrompetteandGitHub f9da3735de Remove workflow feature flag (#12732)
Removing workflows from the lab
2025-06-19 13:26:00 +00:00
Raphaël BosiandGitHub cbc0d06a2f Replace hotkey scopes by focus stack (Part 1 - Dropdowns and Side Panel) (#12673)
This PR is the first part of a refactoring aiming to deprecate the
hotkey scopes api in favor of the new focus stack api which is more
robust.

The refactored components in this PR are the dropdowns and the side
panel/command menu.

- Replaced `useScopedHotkeys` by `useHotkeysOnFocusedElement` for all
dropdown components, selectable lists and the command menu
- Introduced `focusId` for all dropdowns and created a common hotkey
scope `DropdownHotkeyScope` for backward compatibility
- Replaced `setHotkeyScopeAndMemorizePreviousScope` occurrences with
`usePushFocusItemToFocusStack` and `goBackToPreviousHotkeyScope` with
`removeFocusItemFromFocusStack`

Note: Test that the shorcuts and arrow key navigation still work
properly when interacting with dropdowns and the command menu.

Bugs that I have spotted during the QA but which are already present on
main:
- Icon picker select with arrow keys doesn’t work inside dropdowns
- Some dropdowns are not selectable with arrow keys (no selectable list)
- Dropdowns in dropdowns don’t reset the hotkey scope correctly when
closing
- The table click outside is not triggered after closing a table cell
and clicking outside of the table
2025-06-19 14:53:18 +02:00
MarieandGitHub 6dd3a71497 [permissions] Activate permissions V2 on new workspaces (#12731) 2025-06-19 12:46:37 +00:00
Paul RastoinandGitHub 4da0152c33 FixuseLazyFetchAllRecords any wrong infer (#12728)
# Introduction
closes https://github.com/twentyhq/twenty/issues/12721
Regression seems to be introduced by
https://github.com/twentyhq/twenty/pull/12653

## Post mortem
### Previously
No mapping on `namePlural` dynamic response data key
```ts
      const rawResult = await fetchMore({
        variables: {
          lastCursor: lastCursor,
          limit,
        },
      });
```

### Now
Mapping is done by the tool we're consuming already
```ts
      const rawResult = await fetchMoreRecordsLazy();

// 
const fetchMoreRecordsLazy = useRecoilCallback(
    ({ snapshot, set }) =>
      async () => {

          //...
           return {
              data: fetchMoreDataResult?.[objectMetadataItem.namePlural],
              totalCount:
                fetchMoreDataResult?.[objectMetadataItem.namePlural]
                  ?.totalCount,
              records: getRecordsFromRecordConnection({
                recordConnection: {
                  edges:
                    fetchMoreDataResult?.[objectMetadataItem.namePlural]?.edges,
                  pageInfo:
                    fetchMoreDataResult?.[objectMetadataItem.namePlural]
                      ?.pageInfo,
                },
              }) as T[],
```

## Concerns
TypeScript did not throw any errors because `RecordConnectionGql` is
typed as any, we should consider adding a generic type defaulted to
unknown
```ts
import { RecordGqlEdge } from '@/object-record/graphql/types/RecordGqlEdge';
import { Nullable } from 'twenty-ui/utilities';

export type RecordGqlConnection = {
  __typename?: string;
  edges: RecordGqlEdge[];
  pageInfo: {
    __typename?: string;
    hasNextPage?: boolean;
    hasPreviousPage?: boolean;
    startCursor?: Nullable<string>;
    endCursor?: Nullable<string>;
    totalCount?: number;
  };
  totalCount?: number;
  [aggregateFieldName: string]: any; // Any is problematic here should be unknown
};
```

Example:
```ts
export type RecordGqlConnection<
  T extends Record<string, unknown> = Record<string, unknown>,
> = {
  __typename?: string;
  edges: RecordGqlEdge[];
  pageInfo: {
    __typename?: string;
    hasNextPage?: boolean;
    hasPreviousPage?: boolean;
    startCursor?: Nullable<string>;
    endCursor?: Nullable<string>;
    totalCount?: number;
  };
  totalCount?: number;
} & T;
```
2025-06-19 14:22:05 +02:00
Baptiste DevessierandGitHub dae282ca0f Use optimistic rendering when executing a workflow with manual trigger (#12695)
This PR adds optimistic rendering at two places:

- In the `runWorkflowVersion`, to create a workflow run entry as fast as
possible in the cache and render it immediately in the side panel.
- In the `ListenUpdatesEffect`, to be sure the cache is properly set; we
also need to set the record in the record store that's used in the
fields card.


## Before


https://github.com/user-attachments/assets/8b360ea9-c292-4e05-82a0-d2f12176bb6f

## After


https://github.com/user-attachments/assets/2d11023c-2ceb-4fa3-a951-187b9a0b5743

### With a slowed-down network


https://github.com/user-attachments/assets/7d2a592a-1ea7-455b-856f-bf3d9d905061

## Follow up

I will create next a PR to ensure the viewport is always set when we
know the dimensions of the nodes.
2025-06-19 14:09:47 +02:00
a6b8830b91 i18n - translations (#12727)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-19 12:21:00 +02:00
nitinandGitHub a8fb039e65 poc - cal.com integration in onboarding flow (#12530) 2025-06-19 15:27:38 +05:30
e4d44e9c39 i18n - translations (#12725)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-19 11:47:22 +02:00
Thomas TrompetteandGitHub 07cf1ed71d Variables not coming from a Record step should be available in Record Picker (#12708)
We want code and webhook variables available in Record Picker since
those can contains uuid.

This PR:
- update `WorkflowVariablesDropdownObjectItems.tsx` so it manages fields
properly
- factorise both dropdown into a commun hook
- update filterOutputSchema.ts so it does not filter fields that are not
FieldMetadata types
- set relation fields as record object in variable schema so those can
be selected as full record

Before


https://github.com/user-attachments/assets/f4f85402-c056-4fd8-8474-d86bef9d4bc3

After


https://github.com/user-attachments/assets/c6589e18-7dfa-4fc8-a525-3a580e265896
2025-06-19 11:33:21 +02:00
martmullandGitHub c16b625752 Fix Canvas display above banner follow up (#12707) 2025-06-19 09:54:24 +02:00
Félix MalfaitandGitHub a3d163f5e5 Improve seeds for timeline activities (#12692)
Keep improving seeds, this time add timeline activities
2025-06-18 23:12:22 +02:00
Antoine MoreauxandGitHub 1bae411e58 fix(): avoid undefined workspaces with appToken when load availableWorkspaces (#12712) 2025-06-18 16:39:06 +00:00
WeikoandGitHub 3acdf369ab [permissions] better object level permissions override handling (#12709)
## Context
- Same logic as role level permission, setting true on any higher
permission will force true on read and removing read will remove higher
permissions. Just a bit more complex here since object level permissions
have 3 possible states instead of a simple bool.
2025-06-18 18:08:01 +02:00
da5ae34109 [permissions] Filter tabs + registered actions according to permissions (#12657)
Note and task tabs in side panel should only show if user has reading
permission on them.

"Go to companies", "Go to workflows", etc. in command menu should only
show is user has reading permission on related objects.

<img width="507" alt="Capture d’écran 2025-06-17 à 11 09 50"
src="https://github.com/user-attachments/assets/3a2a4c25-0b9b-4ee6-b18f-b019b8a56d47"
/>
<img width="505" alt="Capture d’écran 2025-06-17 à 11 09 56"
src="https://github.com/user-attachments/assets/8a219955-cc8e-4dbf-a4f9-a50e1aaa4b59"
/>

**How to test** 
Assign a user with a custom role that has **no** read permissions on
notes/tasks/workflows/companies/opportunities/people (no need to test
them all but at least one between note and tasks; workflows; one between
companies/opportunities/people). Check that you don't see the related
tab / action.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-18 15:12:58 +00:00
MarieandGitHub e77e7e3149 [permissions] Adapt defaultPath to permissions (#12689)
We had two linked issues
1. default path was not taking permissions into account and could link
to an object user does not have read access on's page
2. visiting the url of an object the user does not have read access on
was possible and returned a "blank" page

Before

https://github.com/user-attachments/assets/e4da1de5-d7e9-4644-ba8e-cd366a9b0fad

After

https://github.com/user-attachments/assets/6576f662-d3a0-4173-8b48-233cc0a04cdf

Also tested with V1.
2025-06-18 16:32:29 +02:00
martmullandGitHub d284fd1d71 Fix authUser decorator usage (#12697)
Solving issue: we don't have `user.firstName` and `user.lastName` set
when signin with e-mail/password. CreateBy, invitation emails and
validation domain email need those info

## Before

## ExecutedBy

<img width="511" alt="image"
src="https://github.com/user-attachments/assets/b85bbda5-f26b-4137-a875-0ef926a1eec4"
/>

## Invitation email

<img width="764" alt="image"
src="https://github.com/user-attachments/assets/107c71bf-a6b2-4291-a31b-6ce48b11dd77"
/>

### Validate domain email

<img width="829" alt="image"
src="https://github.com/user-attachments/assets/213ff7c5-f86d-476f-8f4d-74299d7eb13d"
/>


## After

## ExecutedBy

<img width="500" alt="image"
src="https://github.com/user-attachments/assets/b4125e84-b355-4280-8611-b4e36e6033c7"
/>

## Invitation email

<img width="754" alt="image"
src="https://github.com/user-attachments/assets/952fe5bf-f4da-4fef-b765-fc220255dedf"
/>

### Validate domain email

<img width="709" alt="image"
src="https://github.com/user-attachments/assets/6950097c-51ae-469b-a7cf-f561650ee86e"
/>
2025-06-18 13:57:55 +00:00
Charles BochetandGitHub 82876bb7d1 Fix table fetchMore flakyness (#12702)
Remove useless debounce + using cacheFirst for fetchMore as fetchingMore
will trigger initial fetch if not already performed
2025-06-18 15:37:22 +02:00
Félix MalfaitandGitHub 56d934872d Fix user signup event (#12700)
Send event for every type of user creation
2025-06-18 15:32:46 +02:00
2ebe437885 i18n - translations (#12701)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-18 13:42:24 +02:00
WeikoandGitHub d98f5a241f fix missing trash x off icon (#12699)
## Context
Icon does not exist in tabler-icon it seems, had to create a new one
manually.

Also added a reload current user when roles are updated to update the
state accordingly

<img width="419" alt="Screenshot 2025-06-18 at 13 06 23"
src="https://github.com/user-attachments/assets/2667883e-c392-4f68-bc04-7471b9bdd6fd"
/>
2025-06-18 13:32:18 +02:00
Antoine MoreauxandGitHub 9612a4928d fix(signinup): several issues (#12698)
- Fixed an issue where you have invitations in your available workspaces
for signup.
- Corrected the URL display in the browser when hovering over the twenty
logo on the sign-in/up form.
- The workspace list is now displayed when you are logged into the
default domain.
2025-06-18 13:13:44 +02:00
c9344cf427 i18n - translations (#12696)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-18 12:20:54 +02:00
EtienneandGitHub 78d39294ef Import - Increase record import limit (#12627)
<img width="700" alt="Screenshot 2025-06-16 at 15 05 09"
src="https://github.com/user-attachments/assets/a09c3fae-c0ae-4a63-8bda-9d29c97a6a66"
/>


closes https://github.com/twentyhq/twenty/issues/11980
2025-06-18 10:13:24 +00:00
EtienneandGitHub 83f28f113a Onboarding - fix infinite loop (#12694)
To reproduce : 
- IS_BILLING_ENABLED=true
- Start creating a workspace. At each onboarding step - Create Profile /
SyncEmails / InviteTeam - suspend your workspace > infinite loop

closes https://github.com/twentyhq/twenty/issues/12272
2025-06-18 11:56:34 +02:00
fb6f2610c5 fix(admin-panel): prevent layout shift when toggling feature flags (#12686)
Closes #12571
~~## What’s broken?~~
~~Toggling a feature flag in the admin panel re-renders the entire table
and uses a Framer Motion slide animation for the knob. Each animation
frame forces a layout recalculation all the way up, causing the page to
“jump.”~~

~~## What’s the fix?~~
~~Swap out the Framer Motion toggle for a pure-CSS version:~~
~~- Container is position: relative~~
~~- Knob is position: absolute and moves via left~~
~~- A transition: left 0.3s ease + will-change: left hint runs on the
compositor layer~~

~~This keeps the smooth slide effect but never triggers parent layout
reflows.~~

~~No changes to the public <Toggle> API or behavior.~~

~~TODO: test all toggles in app and stories if any~~

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-18 11:56:19 +02:00
martmullandGitHub 657b87fd0c Fix banner z-index (#12683)
## Before

![image](https://github.com/user-attachments/assets/177e8ce2-eaba-442c-a10a-e3a44c91114f)

## After
<img width="1338" alt="image"
src="https://github.com/user-attachments/assets/d44da1b7-0d82-4b04-91b4-cbaa404e9da2"
/>
2025-06-18 11:46:23 +02:00
e00b75e63d i18n - translations (#12693)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-18 00:47:21 +02:00
WeikoandGitHub 6650d4b059 Add delete role action (#12691)
## Context
Add delete role action, the backend takes care of most of the operations
(can't delete a default role, can't delete the admin role, re-assign
existing members to default role...)

<img width="592" alt="Screenshot 2025-06-17 at 20 24 21"
src="https://github.com/user-attachments/assets/3f01f12c-d8a4-466c-b4c7-9674f597a7a8"
/>

<img width="567" alt="Screenshot 2025-06-17 at 20 24 24"
src="https://github.com/user-attachments/assets/8aceaf6c-3082-4ca6-a4dd-9767fc186923"
/>
2025-06-18 00:43:23 +02:00
Thomas TrompetteandGitHub 338f08b3a4 Remove unused hook useSelectFilterFromViewBarFilterDropdown (#12687)
As title
2025-06-17 23:52:38 +02:00
GuillimGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Charles Bochet
c72ecde094 fixing index on relations (#12602)
## Why

After the changes on relations, index on relations were skipped by the
syncmetadata service, so no more migrations were generated for relation
fields.

We wanted to fix this.


## Test

This PR adds unit tests for the `createIndexMigration` utility in the
workspace migration builder. The tests cover:

- Creating index migrations for simple fields (e.g., text fields)
- Creating index migrations for relation fields (ensuring correct column
naming, e.g., `authorId` for the `author` objectmetadataname)


## Excluded
The delete index on relation does not need the column names so i don't
think i needed to work on this method. I might be wrong.


## Checklist

- [x] Added/updated unit tests for index migration creation
- [x] Verified correct handling of simple and relation fields
- [x] Ensured all tests pass

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-17 18:22:08 +02:00
Lucas BordeauandGitHub 1d703bbf2b Fix single picker dropdown search filter (#12688)
This PR fixes the single record picker search filter that wasn't reset
on close, thus preventing from having the result of a previous search
when re-opening a single record picker.

Before : 


https://github.com/user-attachments/assets/85a3a780-f010-4b63-8c86-2ed28202e9fd

After : 



https://github.com/user-attachments/assets/2db082b5-add2-4952-b812-6a4f24cb3b26


Fixes https://github.com/twentyhq/twenty/issues/12667
2025-06-17 17:44:29 +02:00
GuillimandGitHub 0ae43f518d catching better internal errors from google (#12663)
Small fix to avoid unknown errors into temporary errors
2025-06-17 16:48:40 +02:00
GuillimandGitHub 1cee587709 Removing trailing slashes (#12658)
Fix inconsistent domain URL formats : removing the last / that was
caused by URL method

Standardize URL formatting to ensure consistent links storage and
retrieval of domain URLs across the application. Will improve the
dedpulicates in the links

Note: there is another temporary issue from google that was solved on
the 13th of june https://groups.google.com/g/adwords-api/c/tRSQMRZrJYM
but we consider this out of this scope

Fixes #12621
2025-06-17 16:29:14 +02:00
Lucas BordeauandGitHub cc7a37b0cc Fix "No results found" in record pickers (#12685)
This PR fixes small bugs around the "No results found" record picker.

Before : 


https://github.com/user-attachments/assets/e2eee648-1cb1-40fb-ad3c-fe4724f7314e

After : 


https://github.com/user-attachments/assets/714e6dea-3c65-4e04-9fef-ee718c94bbba

Minor improvements : 
- Created a new component `RecordPickerNoRecordFoundMenuItem` to
abstract this "No records found" menu item
- Removed `not-allowed` cursor from MenuItem in disabled state.

Fixes https://github.com/twentyhq/twenty/issues/12666
2025-06-17 16:10:44 +02:00
c88495b545 i18n - translations (#12684)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-17 16:05:27 +02:00
WeikoandGitHub c79daced48 Fix readonly mode with permissions v2 for tables (#12617)
isReadonly was not set anymore, this PR put it back with the new
permission check
Also fix missing readonly mode for title cell
2025-06-17 14:03:50 +00:00
WeikoandGitHub 8f07f681d2 role settings various fixes + update role object level permission design (#12664)
<img width="944" alt="Screenshot 2025-06-17 at 12 10 07"
src="https://github.com/user-attachments/assets/abfda0c2-3266-465c-b98e-7bf78660a057"
/>
<img width="943" alt="Screenshot 2025-06-17 at 12 10 00"
src="https://github.com/user-attachments/assets/8fd28479-1f55-4f3a-815c-1195154d3305"
/>
<img width="667" alt="Screenshot 2025-06-17 at 12 09 49"
src="https://github.com/user-attachments/assets/8d444523-4e43-4b59-95bb-45dc5fac5520"
/>
<img width="632" alt="Screenshot 2025-06-17 at 12 09 42"
src="https://github.com/user-attachments/assets/8a1e45bb-7fde-42a6-9f2d-79cbec8121cd"
/>
<img width="643" alt="Screenshot 2025-06-17 at 12 09 36"
src="https://github.com/user-attachments/assets/43f80a92-16e2-4a0e-8a07-2f3e7278ff4a"
/>
2025-06-17 14:00:31 +00:00
f10abec505 fix(front): import missing fragment (#12678)
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
2025-06-17 13:50:12 +00:00
834ae3ceb5 Adjutment to the padding (#12619)
it is an unusual 2.75 here.

I tried to set it to 3 however it requires a big re-work on all cells of
the table. The main concern being the new border left of 1px for the
"focus mode"

Note: to be fair, we are not 100% aligned with the Figma on the paddings
and alignment contruction. It is not related to this issue, but makes
this fix not ideal since not aligned with our CSS standards.

Fixes https://github.com/twentyhq/twenty/issues/12607

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-17 15:45:00 +02:00
Charles Bochet bcfa08389b Fix linter on main 2025-06-17 15:37:05 +02:00
martmullandGitHub 27e661d76f Deactivate workflow when deleted (#12677)
## Done
Update manually (without status update job) workflow and
workflowVersions statuses when workflow is deleted

## Not Done
Status optimistic rendering on workflow index deleted page. This page is
already buggy, this will be fix by
https://discord.com/channels/1130383047699738754/1384177035244732487
2025-06-17 15:33:06 +02:00
a47a6be4a8 Improve seeds (#12675)
- Add seeds for notes/tasks
- Adds account manager to companies
- A companies and phone numbers to people
- Add many more opportunities

TODO: add timeline activities

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2025-06-17 15:25:05 +02:00
Charles BochetandGitHub f3a8b849aa Fix table loading (#12653)
As per title
2025-06-17 15:01:28 +02:00
fb9d5066dc Add basic UUID support to filters (#12676)
- Only operands IS
- Do not set filter when no valid uuids or variables
- Allow ID field to be filterable despite being system



https://github.com/user-attachments/assets/e1c67103-728f-4798-91c6-4aea162f8698

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-06-17 14:58:50 +02:00
Lucas BordeauandGitHub 01a69f6288 Fixed single record picker missing dropdown separator (#12672)
This PR fixes a missing dropdown menu separator when no result found in
a single record picker.

Before : 


![image](https://github.com/user-attachments/assets/77ea2275-cace-443b-b691-bab52dd8cfc0)

After : 

<img width="233" alt="image"
src="https://github.com/user-attachments/assets/73919d63-3126-4b56-b335-34d3c9d6ac15"
/>

Fixes https://github.com/twentyhq/twenty/issues/12665
2025-06-17 14:30:17 +02:00
Raphaël BosiandGitHub efe1700cc8 Set hotkey scope when navigating in side panel's history (#12634)
This PR fixes a bug where the side panel couldn't be closed after the
execution of a workflow with a form. After the execution of the
workflow, `goBackFromCommandMenu` is called to show the workflow run.
The hotkey scope wasn't reset properly, and the click outside listener
from the side panel is only triggered when the scope is
`CommandMenuFocused`.

This PR sets the hotkey scope to `CommandMenuFocused` when going back or
when navigating inside the command menu history.

Note: (we don't use `setHotkeyScopeAndMemorizePreviousScope` here
because we don't need to memorize the active hotkey scope of the page we
are leaving)

Before:


https://github.com/user-attachments/assets/09edf97b-7520-46ce-ade3-6bb6b15ef435


After:


https://github.com/user-attachments/assets/16c288cb-1d42-4099-8925-74a673f7a479
2025-06-17 13:37:27 +02:00
EtienneandGitHub 99480e044f Import - fix uuid field import (#12659)
[Added here

](https://github.com/twentyhq/twenty/pull/12489/files#diff-4aeb04b117d39d98f2bcdc6045f825888419f4f6c96496b4278b9f2bcc1b95c6R287)
but
[accidentally removed during rebase
here](https://github.com/twentyhq/twenty/pull/12615/files#diff-4aeb04b117d39d98f2bcdc6045f825888419f4f6c96496b4278b9f2bcc1b95c6L287)
2025-06-17 13:16:27 +02:00
MarieandGitHub 2877b28afb [permissions] Enable permissionsV2 in seeds (#12623)
In this PR

- enable permissions V2 in seeds 
- remove permission V2 toggle in tests
2025-06-17 09:56:11 +00:00
martmullandGitHub 54090a0340 Fix icon button group design (#12656)
- remove not expected animation
- move border to iconButtonGroup ui component
2025-06-17 11:16:53 +02:00
EtienneandGitHub 713d3defef Import - Upsert on composite fields (#12615)
To test : 
- Import a record with Id column (for upsert-ing) + some subfields in
each composite fields. Check that only matched subfields are updated
(Main issue)
- Import a record with a multi-select field - Check it works + Match
multi-select field on a non multi-select column, check it does not work.
(Specific bug fixed in second commit is : undefined value in multi
select column (corresponding to no item selected) caused error in
multi-select parsing).

closes https://github.com/twentyhq/core-team-issues/issues/990
2025-06-17 11:07:51 +02:00
Thomas TrompetteandGitHub 093073d5e2 Hide runs by default on workflow index view (#12652)
Too many runs cause perf issues on index page. Let's hide this field
until we improve the way we fetch relations
2025-06-17 11:06:04 +02:00
Thomas TrompetteandGitHub f7396e3531 Enable find records action + Implement readonly (#12636)
- Add readonly in context
- Avoid using it in AdvancedFilters component directly. Keeping it
workflow related

<img width="495" alt="Capture d’écran 2025-06-16 à 18 23 34"
src="https://github.com/user-attachments/assets/dfdfdb71-d5a9-4eed-8938-b06790c62bcd"
/>
2025-06-17 11:02:13 +02:00
Lucas BordeauandGitHub 18d154282e Harmonize filter and sort dropdown width (#12649)
This PR sets the same width for all dropdowns used in filter and sort
features.

We use GenericDropdownContentWidth. ExtraLarge (320px) as specified on
Figma :
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=44490-81923&t=h6KWtlM5WUm4aujY-11

Fixes https://github.com/twentyhq/core-team-issues/issues/1004
2025-06-17 10:26:31 +02:00
Charles BochetandGitHub 0043665202 BREAKING CHANGE: Fix broken support button (#12648)
## Context 

Support button was missing for configuration having support enabled
(FrontApp)

<img width="1253" alt="image"
src="https://github.com/user-attachments/assets/930e3e0c-05a1-4a5b-820b-bb257f19fdde"
/>


## How

Recently, we changed some enums from lowercase to uppercase in graphql

## Problem resolution

supportDriver was typed as a string where we could have used
SupportDriver type. I'm exposing it in the graphql generated files to
re-use in the front so this issue cannot happen anymore
2025-06-17 10:26:22 +02:00
martmullandGitHub ccd16fb27f Display + edge icon on hover (#12635) 2025-06-17 10:17:58 +02:00
MarieandGitHub 15c703c01e [permissions] allow checkoutSession if workspace is pending_creation (#12638)
Closes https://github.com/twentyhq/core-team-issues/issues/992

Occasionaly, users can have a subscription created but still have their
workspace not activated and therefore not have a role yet, if they did
not go through the whole flow the first time. This causes a permission
check error while calling checkoutSession, while it shouldn't.

We detected the error through sentry. Since there has been no occurences
for the past three weeks in aggregateCompanies and getCurrentUser
transactions (while we have daily errors in checkoutSession), I assume
it has been fixed in the meantime. If not it will pop again on sentry
anyway !
<img width="798" alt="Capture d’écran 2025-06-16 à 18 38 43"
src="https://github.com/user-attachments/assets/2067c166-8b19-4c83-9270-6e49ee7ae0f5"
/>
2025-06-17 09:16:22 +02:00
Félix MalfaitandGitHub c7b4001c3d Migrate cursor rules (#12646)
Migrating rules to new format but they should be re-written entirely, I
don't think they help much and are not auto-included (except
architecture)
2025-06-17 07:54:02 +02:00
0b9280a4fc Fix path typo for timeline repositories (#12640)
## Summary
- rename `timeline/repositiories` dir to `repositories`
- update all imports referencing the new `repositories` path

## Testing
- `git status --short`

------
https://chatgpt.com/codex/tasks/task_e_68506cd0782c8320aea78cb452f228a0

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-06-16 23:53:56 +02:00
Charles BochetandGitHub d1e0af7f38 Improve sync performances (#12639)
## Goal

We have identified that sync-metadata (which is called during new
workspace initialization) is slow mainly because of workspaceMigration
application (migration-runner module). This is due to the fact that we
use typeORM API to perform schema changes, which often query the
existing schema. As querying the existing schema is costly (especially
with ~1M existing columns) and as we already have what we need described
as metadata, we will use raw SQL directly. This should divide the
workspace initialization time by x2.

## How

This PR can be read in two commits:

1. Extract functions tied to column migrations in a separate service
(`workspace-migration-column.service`) + deprecate COMMENT column
migration type which is not useful since we are not using pg-graphql
anymore
2. Re-work `workspace-migration-column.service` to make it clearer + use
raw SQL

## Result

Before:
<img width="1367" alt="image"
src="https://github.com/user-attachments/assets/e730df7b-db7f-4433-9ce5-52841b010990"
/>

After:
<img width="1367" alt="image"
src="https://github.com/user-attachments/assets/72d2c2b1-2475-4541-a3d5-50b70824a2e4"
/>



## Manual Testing

- Sync-metadata OK
- Workspace init OK
2025-06-16 23:53:42 +02:00
Félix Malfait 497faca574 feat: Add Cursor background agent configuration with PostgreSQL and Redis setup 2025-06-16 22:42:57 +02:00
Félix MalfaitandGitHub 47a03e3907 Fix typos in website README (#12641)
## Summary
- fix typos in `packages/twenty-website/README.md`

## Testing
- `npx nx format:check` *(fails: Could not find Nx modules)*

------
https://chatgpt.com/codex/tasks/task_e_68506cb30dcc832095fbe4b9b360fe8d
2025-06-16 21:27:59 +02:00
martmullandGitHub 878e1dbfd9 Remove actions when record deleted (#12633)
## All Objects
Remove from deleted records view for all object:
- NoSelectionRecordActionKeys.CREATE_NEW_RECORD
- NoSelectionRecordActionKeys.IMPORT_RECORDS
- SingleRecordActionKeys.ADD_TO_FAVORITES
- SingleRecordActionKeys.REMOVE_FROM_FAVORITES

Remove from index view for deleted record:
- DELETE
- ADD_TO_FAVORITES
- REMOVE_FROM_FAVORITES

## Workflows
Remove from deleted workflows view:
- NoSelectionWorkflowRecordActionKeys.GO_TO_RUNS
- SingleRecordActionKeys.EXPORT

Remove from index view for deleted workflow:
- ACTIVATE
- DEACTIVATE
- DISCARD_DRAFT
- SEE_ACTIVE_VERSION
- SEE_RUNS
- SEE_VERSIONS
- TEST
2025-06-16 17:20:13 +02:00
Thomas TrompetteandGitHub 22dade6ef7 Fix remaining field issues for find record action (#12628)
- Handle currency code and country multiselect fields

Before / After
<img width="252" alt="Capture d’écran 2025-06-16 à 15 24 35"
src="https://github.com/user-attachments/assets/3e921ffa-33cb-41dd-82d7-ef3a1aef3510"
/> <img width="252" alt="Capture d’écran 2025-06-16 à 15 24 47"
src="https://github.com/user-attachments/assets/115d18b8-7a15-46b1-8786-bd63b7bb1989"
/>

- Use action button rather than light icon button to match figma. Asked
@Bonapara, we want it for both workflow and index page

Before
<img width="252" alt="Capture d’écran 2025-06-16 à 15 25 02"
src="https://github.com/user-attachments/assets/ec376c70-d2df-417b-aefc-625e965dded1"
/>

After
<img width="252" alt="Capture d’écran 2025-06-16 à 15 23 50"
src="https://github.com/user-attachments/assets/1824ff86-b5f1-47ad-8b5c-7ea84e0e3ac6"
/> <img width="400" alt="Capture d’écran 2025-06-16 à 15 25 40"
src="https://github.com/user-attachments/assets/f2daba64-0982-40ee-9662-a23f86385a8f"
/>

- Remove `isRelative` from date field option for workflows
2025-06-16 16:32:10 +02:00
Lucas BordeauandGitHub e922843afb Created DropdownMenuInnerSelect and implemented it for filter dropdowns (#12626)
This PR introduces a new generic UI component DropdownMenuInnerSelect,
that improves the UI by allowing to have both a dropdown menu header and
a select in the header.

In this PR we implement it just for filter dropdown components.

Fixes https://github.com/twentyhq/core-team-issues/issues/1001
2025-06-16 16:16:32 +02:00
Raphaël BosiandGitHub ed1593c089 Fix shortcuts inconsistencies (#12624)
Fixes https://github.com/twentyhq/core-team-issues/issues/1093

The search shortcut and the go to shortcuts were not always available.
They worked after a refresh but not when clicking outside of a table or
a board, or when a table row or board card was focus.
This PR fixes this:


https://github.com/user-attachments/assets/f454037b-9dfd-4f9c-9124-43f4b8b5cec8
2025-06-16 16:10:27 +02:00
e41d2f9f53 i18n - translations (#12630)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-16 16:07:24 +02:00
0349003775 Force close dropdown when using cmdK (#12506)
### Issue: 
overflow of input fields when opening the side panel.

Could be imporved with a better command menu state handling

### Solution:
In command menu hooks, we now close all dropdowns when opening the side
panel. This ensures all UI elements are close properly before the
sidepanel shows up

Fixes : https://github.com/twentyhq/twenty/issues/12485

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-16 16:07:13 +02:00
MartyandGitHub 6a224241ec Fix inconsistent volume path in docker-compose.yml (#12479)
*Title:* Align volume mount path for `server-local-data` in
`docker-compose.yml`

**Description:**

This pull request resolves a configuration inconsistency in the
`docker-compose.yml` file related to the `server-local-data` volume used
by the `server` and `worker` services.

### Background

The `server` and `worker` services are both configured to use a shared
volume named `server-local-data`. However, the volume mount paths
differ:

* The `server` service uses a hardcoded mount path:

  ```yaml
  - server-local-data:/app/packages/twenty-server/.local-storage
  ```

* The `worker` service uses a path that supports an environment variable
override:

  ```yaml
-
server-local-data:/app/packages/twenty-server/${STORAGE_LOCAL_PATH:-.local-storage}
  ```

This discrepancy can result in the two services referencing different
filesystem locations, especially when `STORAGE_LOCAL_PATH` is set. This
may lead to runtime errors or unexpected behavior when accessing local
storage.

### Proposed Change

This PR standardizes the volume mount path in the `worker` service to
use the same environment variable-based path as the `server` service:

```yaml
- server-local-data:/app/packages/twenty-server/.local-storage
```

### Rationale

* Ensures consistent and predictable volume mount behavior across
services.
* Prevents potential data inconsistencies or access issues arising from
differing mount points.

### Impact

* No breaking changes expected if `STORAGE_LOCAL_PATH` is not defined.
* Services will now operate on the same volume path, whether or not the
environment variable is set.
2025-06-16 16:04:21 +02:00
c16ba6a7d7 download record sample - Import (#12489)
<img width="400" alt="Screenshot 2025-06-10 at 18 14 17"
src="https://github.com/user-attachments/assets/05591b46-c36d-45c6-a236-3469c29d7420"
/>


closes https://github.com/twentyhq/core-team-issues/issues/915

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-16 16:01:27 +02:00
Raphaël BosiandGitHub 79b8c4660c Fix side panel closing when clicking on workflow nodes or options (#12629)
This bug was introduced by
https://github.com/twentyhq/twenty/pull/12609. This previous PR was made
to prevent interacting with elements behind the side panel when it is
opened. But in the workflow visualizer we need to interact with the
diagram nodes.

Fix: add the workflow visualizer nodes and options to the excluded click
outside ids of the side panel.



https://github.com/user-attachments/assets/1fb770d6-1c17-4ac1-b1a9-ed162bdbe298
2025-06-16 13:52:05 +00:00
b0cce3d74a Enable multiple row selection with Shift + checkbox click (#12492)
resolve #12291
This PR enables the selection of multiple rows by clicking checkboxes
while holding the Shift key.

A new Recoil state was created to store the lastRecordSelectedId.
When the user clicks a checkbox while pressing Shift, the index of
lastRecordSelectedId is retrieved, and a loop is executed between the
current row index and the last selected index to select all rows in
between.



https://github.com/user-attachments/assets/97bdf2a0-f6a6-4f9f-8045-3804268ef924

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
2025-06-16 15:51:37 +02:00
Ajay A AdsuleandGitHub 16bccc19e8 fix: move icon state update to useEffect in ObjectOptionsDropdownMenu… (#12611)
Fixed a React state update issue in the
ObjectOptionsDropdownMenuViewName component where the icon state was
being updated during render, causing a React warning.

### What was the issue?
- The code was updating the view's icon state
(`setViewPickerSelectedIcon`) on component mount
- This triggered React's warning: "Cannot update a component while
rendering a different component"

### How was it fixed?
- Moved the state update into a `useEffect` hook
- The icon state now updates properly after component render
- Added proper dependencies to the `useEffect` hook (`currentView.icon`
and `setViewPickerSelectedIcon`)



https://github.com/user-attachments/assets/b3b6b3ba-16cd-4d9a-83db-eea96dc51bd6


fix #11852
2025-06-16 15:13:53 +02:00
Baptiste DevessierandGitHub e3addb2234 Improve VariableChip design (#12610)
## Before

![CleanShot 2025-06-16 at 12 03
33@2x](https://github.com/user-attachments/assets/2fa6ec21-2947-48df-b447-aab298b9a480)

![CleanShot 2025-06-16 at 12 03
26@2x](https://github.com/user-attachments/assets/74f36b2f-cec7-40a1-9f99-453fbdb75669)

![CleanShot 2025-06-16 at 12 08
34@2x](https://github.com/user-attachments/assets/b4c920ee-377c-43b6-b809-545d441a0d8c)


## After

![CleanShot 2025-06-16 at 12 02
18@2x](https://github.com/user-attachments/assets/28720f15-997a-4600-9b5f-ed50a9422329)

![CleanShot 2025-06-16 at 12 02
43@2x](https://github.com/user-attachments/assets/875df203-07dc-4c95-8411-7e084ea25dbd)

![CleanShot 2025-06-16 at 12 08
12@2x](https://github.com/user-attachments/assets/48bacf2a-ee16-4894-a288-9d8113fa4f45)
2025-06-16 14:59:12 +02:00
dc6ca53dbd i18n - translations (#12625)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-16 14:43:16 +02:00
EtienneandGitHub 5a9622ee8b update billing prices display (#12622)
<img width="410" alt="Screenshot 2025-06-16 at 11 56 05"
src="https://github.com/user-attachments/assets/ffddf6e7-d9b6-4d18-9c0b-fcdc9f9e2632"
/>


closes https://github.com/twentyhq/core-team-issues/issues/1012
2025-06-16 14:25:50 +02:00
Thomas TrompetteandGitHub ae57e67c77 Search action - Add variables to select and relations + other fixes (#12604)
- Variables can now be handled for select/multiselect/relations
- Hide field not supported in forms (source, rating)
- Add tests for schemas

Remaning issues:
- country/currency pickers not working
- stories for components
- variable picker hidden for dates
2025-06-16 13:45:28 +02:00
martmullandGitHub e0cb53af48 1031 workflows menu fixes (#12618)
## Before (not exhaustive)
<img width="520" alt="image"
src="https://github.com/user-attachments/assets/642365c5-f359-4ad3-8ba3-d7bb9c7d91e4"
/>
<img width="522" alt="image"
src="https://github.com/user-attachments/assets/0819717f-84c6-436c-b9f4-20a1964cd565"
/>
<img width="528" alt="image"
src="https://github.com/user-attachments/assets/240bf181-ec37-4e25-9fdb-c264a680abcc"
/>
<img width="525" alt="image"
src="https://github.com/user-attachments/assets/0dfd55c1-dfbd-47ee-8741-977b5e57fa0a"
/>


## After (not exhaustive)
<img width="511" alt="image"
src="https://github.com/user-attachments/assets/199b6e6e-be1d-4b75-8df6-d65ff05bee58"
/>
<img width="512" alt="image"
src="https://github.com/user-attachments/assets/a92f67a8-ed58-4c4f-b401-07765158030f"
/>
<img width="522" alt="image"
src="https://github.com/user-attachments/assets/ba3ae73a-4650-4f7f-a62a-980e6a2d21d1"
/>
<img width="518" alt="image"
src="https://github.com/user-attachments/assets/97946870-4fba-4898-8381-9087df0b9ac4"
/>
2025-06-16 11:40:27 +00:00
MarieandGitHub cdc4badec3 [permissions] Writing permission does not go without reading permission (#12573)
Closes https://github.com/twentyhq/core-team-issues/issues/868

We should not allow to grant any writing permission (update, soft
delete, delete) on an object or at role-level without the reading
permission at the same level.

This has been implemented in the front-end at role level, and is yet to
be done at object level (@Weiko)
2025-06-16 10:04:38 +00:00
bee1717d37 i18n - translations (#12620)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-16 12:00:04 +02:00
a44ba2065d feat: add short number formatting option to number field (#12613)
resolve #11927
Add a new 'Short Number' option that disables decimals and resets the
value to 0 when selected.


https://github.com/user-attachments/assets/d3524115-e3ec-4a07-9dbf-e19d03cf65dd



https://github.com/user-attachments/assets/2f2b46d1-06d9-4a92-8f37-0291d46accab

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-06-16 11:48:18 +02:00
MarieandGitHub 929586e4a9 [permissions] Fix rest api (#12608)
We need to use twentyORMManager and not twentyORMGlobalManager in rest
api base handler, because we don't want to bypass permissions using
`shouldBypassPermissions` parameter (which we would have to do to use
twentyORMGlobalManager).

ScopedWorkspaceContextFactory was not adapted to rest api requests which
form differs from graphql request.
2025-06-16 10:42:55 +02:00
Lucas BordeauandGitHub a05c659e03 Improved date filter input behavior (#12596)
Opening a date picker when creating a filter now directly applies
today's date to avoid any in-between state issues.

This allows the date picker and the operand selection to behave nicely
when creating a date filter.

Fixes https://github.com/twentyhq/core-team-issues/issues/1049
2025-06-16 10:35:20 +02:00
Raphaël BosiandGitHub 6d6738e7cb Fixes on side panel closing and table rows and board cards activation (#12609)
Fixes https://github.com/twentyhq/core-team-issues/issues/1096

This PR:
- Prevents interaction with elements inside the index page when the side
panel is opened, except for switching between records
- Prevents stacking multiple records in the side panel navigation stack
when navigating from the index
- Adds activation and unfocus logic for board cards when clicked
- Fixes table row activation after clicking on a record chip

Before:


https://github.com/user-attachments/assets/dcfec9fb-392b-4760-9b11-b0f077087b82


After:


https://github.com/user-attachments/assets/93e0dc6a-c693-4484-b23e-f5ae291eb472
2025-06-16 10:33:57 +02:00
GuillimandGitHub 46d6e7a8bc avoid nullable values (#12606)
Update the default set of system fields for custom objects, to ensure
position is not nullabel and has a default value to 0

Steps to reproduce :
create a custom object,
send a POST request with body ```{position:null}```
the record should be created

After the change, 
an error will be thrown
<img width="754" alt="Screenshot 2025-06-13 at 17 16 56"
src="https://github.com/user-attachments/assets/d40931f7-16cc-4b68-8dbb-deb0fa292be5"
/>
2025-06-16 10:20:23 +02:00
9e49e87646 fix: correct inverted permission checks for create buttons (fix #12581) (#12614)
## Summary
This PR fixes inverted permission checks that were preventing authorized
users from seeing "Add New" and "Add note" buttons while showing them to
unauthorized users.

## Changes
- Fixed permission check in `SingleRecordPickerMenuItemsWithSearch`
component (2 locations)
- Fixed permission check in `Notes` component

## Issue
These permission checks were incorrectly using
`\!hasObjectUpdatePermissions` (NOT has permissions) when they should
have been checking `hasObjectUpdatePermissions` (has permissions).

This is similar to the issue mentioned in PR #12437.

## Test plan
- [ ] Verify that users WITH update permissions can see the "Add New"
button in record pickers
- [ ] Verify that users WITHOUT update permissions cannot see the "Add
New" button
- [ ] Verify that users WITH update permissions can see the "Add note"
button in Notes component
- [ ] Verify that users WITHOUT update permissions cannot see the "Add
note" button

🤖 Generated with Claude Code (https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-06-16 10:02:53 +02:00
Baptiste DevessierandGitHub 43bc55efcd Move the viewport of the workflow visualizer on the show page when side panel is opened (#12605)
The viewport was moved before the flow finished initializing. I created
a state to prevent moving the viewport before the flow has been
initialized, allowing us to compute the bounds of the nodes correctly.

## Before


https://github.com/user-attachments/assets/0f034daf-c29c-4d54-905b-191eb60477a9

## After



https://github.com/user-attachments/assets/1f9018ad-ff97-4cf2-997e-d6b7dadf1f30

## Bonus 🎉 

The viewport is no longer progressively zoomed out, as it was before:



https://github.com/user-attachments/assets/0b985c22-ef06-4226-92a0-e5da569876ff
2025-06-16 09:58:31 +02:00
Félix MalfaitandGitHub 94376e8509 Delete changelog directory (#12612) 2025-06-15 17:19:36 +02:00
martmullandGitHub dde3ca4549 803 timebox improve the ux when creating a new step (#12599) 2025-06-13 17:22:49 +02:00
Antoine MoreauxandGitHub 671a7fbd28 fix(): captcha refresh after signup (#12598) 2025-06-13 15:01:05 +00:00
a617001520 i18n - translations (#12603)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-13 16:35:24 +02:00
Antoine MoreauxandGitHub b1af98f93d refactor(auth): add workspaces selection (#12098) 2025-06-13 16:17:35 +02:00
Paul RastoinandGitHub 836e2f792c Remove selected record id on related relation record detach (#12591)
# Introduction
Verified for multi select record picker and it's already working
Also works for both single and multi after record deletion
Fixes https://github.com/twentyhq/twenty/issues/12544
2025-06-13 14:07:35 +00:00
d494a3e7e9 i18n - translations (#12601)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-13 16:01:13 +02:00
EtienneandGitHub 8e007c8b5f Import - fixes (#12569)
<img width="800" alt="Screenshot 2025-06-12 at 15 22 49"
src="https://github.com/user-attachments/assets/afaa4ef1-b16c-4c05-ba4a-d77ad2ccfa76"
/>


To test : 
- unselect an option on select/multi-select matching (matching step)
- match a mutli-select field with an other field

closes : https://github.com/twentyhq/core-team-issues/issues/1065
closes : https://github.com/twentyhq/core-team-issues/issues/1066
2025-06-13 13:52:32 +00:00
6bca562c65 i18n - translations (#12600)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-13 15:49:09 +02:00
EtienneandGitHub 312632e686 update import auto matching (#12552)
<img width="800" alt="Screenshot 2025-06-11 at 17 45 13"
src="https://github.com/user-attachments/assets/ecc04d41-d74a-424a-9f83-14a793cf4268"
/>

closes https://github.com/twentyhq/core-team-issues/issues/905
2025-06-13 15:43:16 +02:00
Paul RastoinandGitHub 57d002d79a Workspace member can be null (#12597)
Following https://github.com/twentyhq/twenty/pull/12110
Fixes https://github.com/twentyhq/twenty/issues/12594
2025-06-13 12:56:11 +00:00
Raphaël BosiandGitHub 96c2f5477c Trigger search on mouse up (#12595)
This fixes one of the issues in
https://github.com/twentyhq/core-team-issues/issues/1093.

See discussion in https://github.com/twentyhq/twenty/pull/12577


https://github.com/user-attachments/assets/f02a8b06-6246-4c9e-b1f2-8d8ce5091cdc
2025-06-13 14:50:30 +02:00
martmullandGitHub 194549b77e Fix flaky test (#12579)
as title, add missing awaits
2025-06-13 12:33:56 +00:00
Raphaël BosiandGitHub fdb5764acd Remove shouldCloseCommandMenuOnClick (#12593)
Remove deprecated prop `shouldCloseCommandMenuOnClick`
2025-06-13 11:58:02 +00:00
43f611c47b i18n - translations (#12592)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-13 13:45:46 +02:00
+23 19b7ab57b9 Feature - HTTP request node (#12509)
Closes [#1072](https://github.com/twentyhq/core-team-issues/issues/1072)



https://github.com/user-attachments/assets/adff3474-6ec3-4369-a0c8-fb4be7defe85

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: guillim <guigloo@msn.com>
Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Thomas des Francs <tdesfrancs@gmail.com>
Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Jordan Chalupka <9794216+jordan-chalupka@users.noreply.github.com>
Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
Co-authored-by: jaspass04 <147055860+jaspass04@users.noreply.github.com>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: Matt Dvertola <64113801+mdvertola@users.noreply.github.com>
Co-authored-by: Zeroday BYTE <github@zerodaysec.org>
Co-authored-by: Naifer <161821705+omarNaifer12@users.noreply.github.com>
Co-authored-by: Karuna Tata <karuna.tata@devrev.ai>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
Co-authored-by: Ajay A Adsule <103304466+AjayAdsule@users.noreply.github.com>
Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
Co-authored-by: oliver <8559757+oliverqx@users.noreply.github.com>
Co-authored-by: Ahmad Zaheer <55204917+ahmadzaheer-dev@users.noreply.github.com>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
2025-06-13 13:41:22 +02:00
Raphaël BosiandGitHub e9733ea33a Fix side panel closing after workflow execution (#12590)
We introduced a new behavior after a workflow execution where the
workflow run would be opened inside the side panel.
But we didn't prevent the side panel form closing. This caused a race
condition between the side panel closing and the reopening where
sometimes the closing would fire after the reopening.

**Fix**: Since we now always want to open the side panel after the
execution, I added
`closeSidePanelOnCommandMenuListActionExecution={false}` for workflow
actions.
2025-06-13 10:10:34 +00:00
Lucas BordeauandGitHub 5fed618528 Fixed overflow scroll bar in dropdowns (#12587)
Following-up PR https://github.com/twentyhq/twenty/pull/12547 which
introduced a last minute fix that broke the overflow UI.

Before : 

<img width="261" alt="image"
src="https://github.com/user-attachments/assets/e4345d7f-1f4e-4cca-9056-33b5f897ad8c"
/>

After : 

<img width="276" alt="image"
src="https://github.com/user-attachments/assets/ca31b50d-5656-43ca-9819-8d065ec5c005"
/>
2025-06-13 11:52:20 +02:00
GuillimandGitHub ac64bab4ee typo (#12586) 2025-06-13 09:23:41 +00:00
GuillimandGitHub ff7e9bc433 upgrade-guide (#12585)
just the documentation upgrade guide for v55
2025-06-13 11:15:27 +02:00
Paul RastoinandGitHub 4182a3d306 Refactor WorkspaceMemberDto transpilation (#12110)
# Introduction

In a nutshell this PR introduces a `workspaceMemberEntity` to
`workspaceMemberDto` transpilation which was not done but commented as
`// TODO` across the `user resolver`.
Also passed on the `Roles` and `UserWorkspacePermissions` transpilation
We now also compute the roles for the `workspaceMember` resolver ( not
only the `workspaceMembers` )
Some refactor

In the following days about to create a PR that introduces integration
testing on the user resolver

## Conclusion
As always any suggestions are more than welcomed ! Please let me know !

## Misc

Following https://github.com/twentyhq/twenty/pull/11914

closing https://github.com/twentyhq/core-team-issues/issues/1011
2025-06-13 09:01:25 +00:00
GuillimandGitHub 7c4ddb9448 for better error, especially from sentry cron monitor (#12574)
After release 55, we found out that CRON job monitor was red for
CronTriggerCronJob

While only 1 workspace was not in the appropriate state, meaning the
whole command was probably failing for only 1 workspace failing.

We suggest here to catch errors per worksspace and simply push to sentry
the error of the errored workspace relative to workflow trigger.
2025-06-13 08:02:26 +00:00
Félix MalfaitandGitHub 05adad4648 Fix incorrect relative path (#12582)
Not sure why we didn't see it before but I see errors in the console on
staging when trying to load the manifest.json
2025-06-13 08:09:06 +02:00
nitinandGitHub 3d57c90e04 refactor: Webhooks (#12487)
Closes #12303

### What’s Changed
- Replace auto‐save with explicit Save / Cancel
Webhook forms now use manual “Save” and “Cancel” buttons instead of the
old debounced auto‐save/update.

- Separate “New” and “Detail” routes
Two dedicated paths `/settings/webhooks/new` for creation and
/`settings/webhooks/:webhookId` for editing, making the UX clearer.

- URL hint & normalization
If a user omits the http(s):// scheme, we display a “Will be saved as
https://…” hint and automatically default to HTTPS.

- Centralized validation with Zod
Introduced a `webhookFormSchema` for client‐side URL, operations, and
secret validation.

- Storybook coverage
Added stories for both “New Webhook” and “Webhook Detail”

- Unit tests
Added tests for the new `useWebhookForm` hook
2025-06-13 05:37:25 +00:00
NaiferandGitHub b160871227 feat: order the object metadata items of the API alphabetically (#12558)
resolve #12549
This PR updates the `findManyWithinWorkspace` function to order the
object metadata items alphabetically by `namePlural` in ascending order.


https://github.com/user-attachments/assets/0be77a37-173f-4cf2-86eb-8f2420d8ff51
2025-06-13 07:09:59 +02:00
Félix MalfaitandGitHub 9f579c84c1 Fix blocknote slash menu issue (#12578)
Fix #12562
2025-06-12 21:15:51 +02:00
0c6da76e88 i18n - translations (#12580)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-12 19:20:11 +02:00
nitinandGitHub a5c0922399 Improve email validation modal design (#12490)
closes https://github.com/twentyhq/core-team-issues/issues/1020
2025-06-12 19:05:36 +02:00
martmullandGitHub 4f307a24b0 Add workflow seed (#12572)
Add "Quick Lead" workflow Manually triggered on no record selected
- form -> first name / last Name / email / job title / company name /
company domainName
- create company
- create person


![quickLead1](https://github.com/user-attachments/assets/972cd025-1940-42d6-aec4-38c650f0eee0)
<img width="1512" alt="Capture d’écran 2025-06-12 à 16 31 26"
src="https://github.com/user-attachments/assets/3c598370-12b1-4bf1-8a09-13926948ffbd"
/>
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/37db685a-ab59-46da-8086-c53cd4a2bac4"
/>
2025-06-12 18:04:46 +02:00
martmullandGitHub 3ba701812b Add display flex on pagePanel (#12568)
## Before


https://github.com/user-attachments/assets/06a4d6e9-7674-4748-937a-ee3bbe5ccc5a

## After


https://github.com/user-attachments/assets/6c2a903b-7720-4fcd-acb9-f106cb05f37b


https://github.com/user-attachments/assets/87b1f7dc-457f-48c6-8622-cb49c2ad3c28
2025-06-12 16:48:01 +02:00
MarieandGitHub 6efadd330f Recompute cached permissions at feature flag update (#12554)
If permissionsV2 feature flag is toggled, we should recompute the
permissions.

We decided to make each WorkspaceXxCacheService Xx-specific (feature
flag, permissions...), so we are not recomputing permission cache from
workspaceFeatureFlagCacheService where feature flags are recomputed,
even if that would be a lower level than FeatureFlagService. This allows
to avoid complex circuclar dependency and keeps a clear purpose for each
service.
2025-06-12 16:33:52 +02:00
Thomas TrompetteandGitHub 7e6d3295d6 Fix search record relations (#12553)
Bunch of fixes:
- fix relations in search records
- allow to update relations in update record action
- fix multi select

<img width="503" alt="Capture d’écran 2025-06-11 à 18 30 40"
src="https://github.com/user-attachments/assets/ab652405-ec18-4454-9a60-c0db4c5df823"
/>
<img width="503" alt="Capture d’écran 2025-06-11 à 18 31 04"
src="https://github.com/user-attachments/assets/70b55e49-58ba-4cc2-b38b-13842714fc28"
/>
2025-06-12 16:33:25 +02:00
martmullandGitHub cf01faf276 965 flow control arrow menu 1/3 add insert step button (#12519)
Add insert step button to workflow edges



https://github.com/user-attachments/assets/7144f722-f1c7-450f-a8eb-c902071986a1



Also fixes `iconButtonGroup` UI component

## Before


https://github.com/user-attachments/assets/7b5f0245-d0e8-48af-9aa5-a29388a1caea


## After



https://github.com/user-attachments/assets/1820874f-aa99-41ae-8254-c76c275ee3ae
2025-06-12 12:14:21 +00:00
MarieandGitHub a189f15313 [permissions] fix workflows + remove shouldBypassPermissionChecks for system objects (#12559)
In this PR 

1. fix workflow step creation by adding forgotten
`shouldBypassPermissionChecks` in WorkflowVersionStepWorkspaceService
2. clarify the rule for twentyORMGlobalManager: do not add unnecessary
`shouldBypassPermissionChecks` for system objects (there are no
object-records permission checks on system objects, they are dealt with
at resolver level)
2025-06-12 13:56:41 +02:00
Antoine MoreauxandGitHub a614e00308 fix(workspace): simplify hostname matching logic in WorkspaceProvider… (#12365)
…Effect

Replaced `getHostnamesFromWorkspaceUrls` with
`isWorkspaceHostnameMatchCurrentLocationHostname` for streamlined
hostname comparison, reducing redundancy and improving logic clarity.

Fix #12295
2025-06-12 13:51:05 +02:00
333d7081ef Refactored and simplified DropdownMenuItemsContainer height management (#12547)
This PR refactors the `DropdownMenuItemsContainer` component and
simplifies its inner parts, which have been modified over months for
different needs without taking the time to have a global approach.

It should however be noted that due to the recent refactor of the
`DropdownContent`, it is now much easier to refactor
`DropdownMenuItemsContainer`, mainly because of the width management
being nicely handled by `DropdownContent` now.

Fixes https://github.com/twentyhq/twenty/issues/11766

# Changes

The `width` props of `DropdownMenuItemsContainer` and its usage in
calling components have been removed.

The multiple ternaries inside `DropdownMenuItemsContainer` have been
reduced to one ternary on `scrollable` props.

The `ScrollWrapper` usage has been removed from
`DropdownMenuItemsContainer`, because the only thing we need is to have
a simple `overflow-y: scroll;` CSS property.

Why ? Because it was previously relevant to have a `ScrollWrapper`, when
we were using an external library, but now that `ScrollWrapper` is a
simple `div` with overflowing, which only benefit is to expose a hook to
imperatively toggle this overflowing behavior from outside (mainly
useful for table fixed row and column), and that we don’t need this for
`DropdownMenuItemsContainer`, then it follows that we just need a simple
overflowing `div` container, which simplifies everything and boils down
our `DropdownMenuItemsContainer` to a straightforward and standard CSS
stack.

We remove the temporary `scrollWrapperHeightAuto` props that was used to
fix a bug in a previous PR, we also rollback `ScrollWrapper` to its
previous state with `width: 100%` and `height: 100%` and removed
`heightAuto` props.

The `hasMaxHeight` props is kept, but the `168` pixels value is
extracted in a constant.

# QA


Component | Comment
-- | --
CommandMenuActionDropdown | Reported bug
https://github.com/twentyhq/twenty/issues/12541
RecordIndexActionMenuDropdown |  
AttachmentDropdown | Cannot test because cannot add a file (currently
broken, maybe because of permissions ?)
CommandMenuContextChipGroups |  
FavoriteFolderNavigationDrawerItemDropdown |  
FavoriteFolderPicker |  
FavoriteFolderPickerFooter |  
AdvancedFilterAddFilterRuleSelect |  
AdvancedFilterFieldSelectMenu |  
AdvancedFilterRecordFilterGroupOptionsDropdown |  
AdvancedFilterRecordFilterOperandSelect |  
AdvancedFilterRecordFilterOptionsDropdown |  
AdvancedFilterSubFieldSelectMenu |  
ObjectFilterDropdownBooleanSelect |  
ObjectFilterDropdownCountrySelect |  
ObjectFilterDropdownCurrencySelect |  
ObjectFilterDropdownNumberInput |  
ObjectFilterDropdownOptionSelect | Fixed “No result” case
ObjectFilterDropdownRecordRemoveFilterMenuItem | Removed because unused
ObjectFilterDropdownTextInput |  
ObjectOptionsDropdownFieldsContent | Spotted bug with icon eye
https://github.com/twentyhq/twenty/issues/12545
ObjectOptionsDropdownHiddenFieldsContent | Spotted bug with icon eye
https://github.com/twentyhq/twenty/issues/12545
ObjectOptionsDropdownLayoutContent | Refactored
DropdownMenuItemsContainer usage with DropdownMenuSeparator, spotted bug
switch view type https://github.com/twentyhq/twenty/issues/12546
ObjectOptionsDropdownMenuContent | Refactored DropdownMenuItemsContainer
usage with DropdownMenuSeparator
ObjectOptionsDropdownLayoutOpenInContent |  
ObjectOptionsDropdownMenuViewName |  
ObjectOptionsDropdownRecordGroupFieldsContent |  
ObjectOptionsDropdownRecordGroupSortContent |  
ObjectSortDropdownButton |  
RecordBoardColumnDropdownMenu |  
RecordBoardColumnDropdownMenu |  
RecordBoardColumnHeaderAggregateDropdownFieldsContent |  
RecordBoardColumnHeaderAggregateDropdownMenuContent |  
RecordBoardColumnHeaderAggregateDropdownOptionsContent |  
MultiItemFieldInput | Added hasMaxHeight on list of items
MultiItemFieldMenuItem |  
RecordGroupsVisibilityDropdownSection |  
MultipleRecordPicker |  
MultipleRecordPickerMenuItems |  
SingleRecordPickerMenuItems |  
SingleRecordPickerMenuItemsWithSearch |  
RecordDetailRelationRecordsListItem |  
RecordTableColumnAggregateFooterDropdownSubmenuContent |  
RecordTableColumnAggregateFooterMenuContent |  
RecordTableHeaderPlusButtonContent |  
RecordTableHeaderPlusButtonContent |  
MultipleSelectDropdown |  
SettingsAccountsRowDropdownMenu |  
ConfigVariableDatabaseInput |  
ConfigVariableOptionsDropdownContent |  
SettingsDataModelNewFieldBreadcrumbDropDown |  
SettingsDataModelFieldSelectFormOptionRow |  
SettingsObjectFieldActiveActionDropdown |  
SettingsObjectFieldInactiveActionDropdown |  
SettingsObjectInactiveMenuDropDown |  
SettingsIntegrationDatabaseConnectionSummaryCard |  
SettingsRoleAssignmentWorkspaceMemberPickerDropdown |  
SettingsRolePermissionsObjectLevelObjectPickerDropdownContent | Cannot
test
SettingsSecurityApprovedAccessDomainRowDropdownMenu | Cannot test
SettingsSecuritySSORowDropdownMenu | Cannot test
SettingsServerlessFunctionTabEnvironmentVariableTableRow | Cannot test
MatchColumnSelectFieldSelectDropdownContent |  
MatchColumnSelectSubFieldSelectDropdownContent |  
SubMatchingSelectInput |  
SupportDropdown |  
IconPicker |  
Select |  
SelectInput |  
CurrencyPickerDropdownSelect |  
PhoneCountryPickerDropdownSelect |  
CustomSlashMenu |  
TabListDropdown | Cannot test
MultiWorkspaceDropdownDefaultComponents | Removed unnecessary
StyledDropdownMenuItemsContainer
MultiWorkspaceDropdownThemesComponents |  
MultiWorkspaceDropdownWorkspacesListComponents |  
UpdateViewButtonGroup |  
ViewBarFilterDropdownFieldSelectMenu |  
ViewFieldsVisibilityDropdownSection |  
ViewPickerContentCreateMode |  
ViewPickerContentEditMode |  
ViewPickerListContent | Add hasMaxHeight to limit the height of view
list
ViewPickerOptionDropdown |  
WorkflowEditTriggerDatabaseEventForm |  
WorkflowVariablesDropdownFieldItems |  
WorkflowVariablesDropdownObjectItems |  
WorkflowVariablesDropdownWorkflowStepItems |  


<!-- notionvc: a3a87101-9944-4b03-a29d-b2974d5ffa9d -->

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-12 12:22:26 +02:00
Baptiste DevessierandGitHub 6b0517943f Prevent empty form steps (#12560)
https://github.com/user-attachments/assets/b9fd0269-fffa-4027-a634-15a5234980f0

Related to https://github.com/twentyhq/core-team-issues/issues/1091
2025-06-12 12:18:38 +02:00
cb5a895963 fix: prevent command menu from closing when clicking items in slash menu (#12555)
resolve #12540 

Prevent command menu from closing by adding new excludedClickOutsideIds
constant.


https://github.com/user-attachments/assets/965075d5-d592-4d50-bb5a-1b2bb561e55a

---------

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-06-12 09:30:10 +00:00
Baptiste DevessierandGitHub 10b97d56d4 Fix chromatic tests (#12551) 2025-06-12 10:17:23 +02:00
Félix MalfaitandGitHub ecbc116f8b Workflow to detect breaking changes (#12532)
New CI to detect breaking changes in the REST API or the GraphQL API
2025-06-11 23:17:41 +02:00
MarieandGitHub 04dd0e50bb [permissions] permissions and workflows (#12436)
In this PR

- Determine object record permissions on workflows objects (workflow,
workflowVersion, workflowRun) base on settings permissions @Weiko
- Add Workflow permission guards on workflow resolvers @thomtrp . **Any
method within a resolver that has the SettingsPermission Guard is only
callable by a apiKey or a user that has the permission** (so not by
external parties).
- Add checks bypass in workflow services since 1) for actions gated by
settings permissions, the gate should be done at resolver level, so it
will have been done before the call to the service 2) some service
methods may be called by workflowTriggerController which is callable by
external parties without permissions (ex:
workflowCommonWorkspaceService.getWorkflowVersionOrFail). This is
something we may want to change in the future (still to discuss), by
removing the guard at resolver-level and relying on
shouldBypassPermissionChecks at getRepository and made in a way that we
only bypass for external parties.
- Add checks bypass for actions performed by workflows since they should
not be restricted in our current vision
- Add tests
2025-06-11 16:47:29 +00:00
Raphaël BosiandGitHub e33f2fadd8 Close command menu after destroy (#12525)
Added an argument `closeCommandMenuFromShowPageOptionsMenu` which allows
us to not only close the parent action menu if the action is located
inside the record page action menu dropdown, but to also close the
command menu after, which is the behavior we want for the destroy
action.
2025-06-11 16:38:04 +00:00
Raphaël BosiandGitHub 17fb47f97c Fix unable to reopen record after going back in side panel (#12523)
Before:


https://github.com/user-attachments/assets/25ab8857-ed83-41be-9952-2108443d3e3c

After:


https://github.com/user-attachments/assets/c161c194-1f41-4197-8d5c-f824c6cb5e73
2025-06-11 18:29:03 +02:00
GuillimandGitHub 3d3543e441 Run deduplicateIndexedFieldsCommand before sync metadata (#12550)
please merge
2025-06-11 18:25:46 +02:00
Raphaël BosiandGitHub 27d0a3766f Make filters and sorts work on record page pagination (#12460)
Fixes #7929 

This PR implements a system to capture and preserve the filters and
sorts when navigating from an index view to a record show page. This
information is stored in a context store component state.

This allows users to navigate between records inside the record page
while maintaining context from the index view.
2025-06-11 18:01:03 +02:00
MarieandGitHub 23cbeec227 Fix missing Add File button (#12548) 2025-06-11 15:54:40 +00:00
afa6f84408 fix: remove pointer cursor and hover effects from readonly form field… (#12017)
Readonly form fields in Workflow Versions were previously showing a
pointer cursor and hover background

This update introduces a `isReadOnly` prop on the StyledFieldContainer,
which is derived from the field's `readonly` state via
`actionOptions.readonly`.

When `isReadOnly` is true:
- The cursor is set to `default` instead of `pointer`.

This ensures a more accurate and user-friendly UI by visually indicating
that the field is non-interactive.


https://github.com/user-attachments/assets/90e5c109-f2a6-4e79-b72d-e2fa6038bf93



#12004

---------

Co-authored-by: Baptiste Devessier <baptiste@devessier.fr>
2025-06-11 17:16:06 +02:00
d4995ab54e Fix cursor-based pagination with lexicographic ordering for composite fields (#12467)
# Fix cursor-based pagination with lexicographic ordering for composite
fields

## Bug

The existing cursor-based pagination implementation had a bug when
handling composite fields.
When paginating through results sorted by composite fields (like
`fullName` with sub-properties `firstName` and`lastName`), the WHERE
conditions generated for cursor positioning were incorrect, leading to
records being skipped.

The previous implementation was generating wrong WHERE conditions:

For example, when paginating with a cursor like `{ firstName: 'John',
lastName: 'Doe' }`, it would generate:

```sql
WHERE firstName > 'John' AND lastName > 'Doe'
```

This is incorrect because it would miss records like `{ firstName:
'John', lastName: 'Smith' }` which should be included in forward
pagination.

## Fix

Create a new util to use proper lexicographic order when sorting a
composite field.

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-11 14:48:03 +00:00
GuillimandGitHub 4cea354838 migrating to 55 (#12537)
- Adjusting the upgrade command to add the 55 command
- Adding a correction to move types to core schema
2025-06-11 16:41:12 +02:00
Paul RastoinandGitHub 3233734d2c [CI] Jest sharding integration tests (#12400)
# Introduction
Introducing jest sharding along github actions matrix in order to
fluidify the process

Note in case we will compute and guard coverage metrics we will need to
merge coverages reports such as we do for the frontend storybooks
integrations tests, from now this is overkill as unused

Related successful run
https://github.com/twentyhq/twenty/actions/runs/15585113583/job/43889477889
2025-06-11 16:05:40 +02:00
Baptiste DevessierandGitHub c8ad9f149c Fix e2e tests and "Use as Draft" (#12536)
Closes https://github.com/twentyhq/twenty/issues/12535
2025-06-11 15:13:19 +02:00
Thomas TrompetteandGitHub cf63bd25e3 Hide search again (#12539)
As title
2025-06-11 14:29:53 +02:00
5a15ecb316 i18n - translations (#12538)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-11 14:22:43 +02:00
Thomas TrompetteandGitHub ee7d4380d1 Build column design for advanced filters (#12534)
Figma
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=45225-472099&p=f&m=dev

A few design items need to be discussed with product (font, add filter
button...) to be consistent with existing advanced filter dropdown. I
will also add stories.

<img width="495" alt="Capture d’écran 2025-06-11 à 11 11 03"
src="https://github.com/user-attachments/assets/1fa2fa1e-b4b1-4456-9f9e-81083b0caac6"
/>
2025-06-11 14:01:00 +02:00
beba4b8313 Add missing overrides on entityManager (#12471)
In this PR

1. Add missing override of insert() method on
WorkspaceSelectQueryBuilder to return our custom
WorkspaceInsertQueryBuilder with permission checks.
2. Replace override implementation of methods on WorkspaceEntityManager
that call createQueryBuilder at a nested internal layer of typeORM (i.e.
not directly in the initial implementation of EntityManager - unlike
findBy for instance -, but in calls done under the hood at a level which
would force us to override entire other classes to pass on our
permissionOptions. It is the case for methods which call typeORM's
EntityPersistExecutor for instance.), to validate permissions and then
allow the subsequent calls to be made without permission checks
3. adapt tests

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-11 12:50:10 +02:00
Baptiste DevessierandGitHub 0b406042a1 Allow many record fields relative to the same record type in workflow forms (#12522)
Relative to https://github.com/twentyhq/twenty/issues/12517

## Before


https://private-user-images.githubusercontent.com/29370468/453438380-58c52f55-9145-40f9-a9e9-caec2a2281ea.mp4?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDk1NzAwODAsIm5iZiI6MTc0OTU2OTc4MCwicGF0aCI6Ii8yOTM3MDQ2OC80NTM0MzgzODAtNThjNTJmNTUtOTE0NS00MGY5LWE5ZTktY2FlYzJhMjI4MWVhLm1wND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTA2MTAlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwNjEwVDE1MzYyMFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWYxY2VlZWVmM2I2ZDBhOGQ3NzdlMjEyZTE3OTg0ZDZmMWRmMjQzZTVmYWM5MmU4NDM1NjkyZjNiYWZmMzUxZTAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.n3nrJ4-I-pUjMz2YripGDHZtKc_P3hSlOFK7apFqVIA

## After


https://github.com/user-attachments/assets/4877ca29-f900-48ea-ba3c-124f910d8cf3
2025-06-11 10:20:40 +02:00
nitinandGitHub 4c81d60dc7 Fix workflow run tab not displaying when navigating from side panel to full page (#12531)
closes https://github.com/twentyhq/core-team-issues/issues/1076
## Problem
When opening a workflow run in the side panel and then navigating to the
full page view, the workflow visualizer tab wouldn't display until the
page was refreshed.

## Root Cause
- In the side panel, tabs are merged into a single "home" tab
- When navigating to full page, the activeTabId state persisted as
"home"
- But the full page view only has a "workflowRun"(flow) tab, not "home"
- TabList was trying to display a non-existent tab, resulting in blank
content

## Solution
Added validation in TabList to check if activeTabId exists in
visibleTabs. If not, it falls back to the first available tab.
2025-06-11 10:17:12 +02:00
Charles BochetandGitHub 251b97ca7f Fix cache issue (#12527) 2025-06-10 19:52:52 +02:00
Charles Bochet 93103210bf Fix merge conflict on import 2025-06-10 17:24:41 +02:00
87e944ca60 i18n - translations (#12521)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-10 17:01:12 +02:00
EtienneandGitHub a15318537f update import steps design (#12463)
closes https://github.com/twentyhq/core-team-issues/issues/916

![Screenshot 2025-06-05 at 10 52
58](https://github.com/user-attachments/assets/ba5b6d65-0c1f-4d63-a197-e61816ec2d55)
![Screenshot 2025-06-05 at 10 53
09](https://github.com/user-attachments/assets/4aed579e-5e0e-4570-9518-b6e8ac604ea6)
![Screenshot 2025-06-05 at 10 53
24](https://github.com/user-attachments/assets/6f716306-ba08-468c-875a-4279991c1abd)
2025-06-10 16:49:37 +02:00
a68895189c Deprecate old relations completely (#12482)
# What

Fully deprecate old relations because we have one bug tied to it and it
make the codebase complex

# How I've made this PR:
1. remove metadata datasource (we only keep 'core') => this was causing
extra complexity in the refactor + flaky reset
2. merge dev and demo datasets => as I needed to update the tests which
is very painful, I don't want to do it twice
3. remove all code tied to RELATION_METADATA /
relation-metadata.resolver, or anything tied to the old relation system
4. Remove ONE_TO_ONE and MANY_TO_MANY that are not supported
5. fix impacts on the different areas : see functional testing below 

# Functional testing

## Functional testing from the front-end:
1. Database Reset 
2. Sign In 
3. Workspace sign-up 
5. Browsing table / kanban / show 
6. Assigning a record in a one to many / in a many to one 
7. Deleting a record involved in a relation  => broken but not tied to
this PR
8. "Add new" from relation picker  => broken but not tied to this PR
9. Creating a Task / Note, Updating a Task / Note relations, Deleting a
Task / Note (from table, show page, right drawer)  => broken but not
tied to this PR
10. creating a relation from settings (custom / standard x oneToMany /
manyToOne) 
11. updating a relation from settings should not be possible 
12. deleting a relation from settings (custom / standard x oneToMany /
manyToOne) 
13. Make sure timeline activity still work (relation were involved
there), espacially with Task / Note => to be double checked  => Cannot
convert undefined or null to object
14. Workspace deletion / User deletion  
15. CSV Import should keep working  
16. Permissions: I have tested without permissions V2 as it's still hard
to test v2 work and it's not in prod yet 
17. Workflows global test  

## From the API:
1. Review open-api documentation (REST)  
2. Make sure REST Api are still able to fetch relations ==> won't do, we
have a coupling Get/Update/Create there, this requires refactoring
3. Make sure REST Api is still able to update / remove relation => won't
do same

## Automated tests
1. lint + typescript 
2. front unit tests: 
3. server unit tests 2 
4. front stories: 
5. server integration: 
6. chromatic check : expected 0
7. e2e check : expected no more that current failures

## Remove // Todos
1. All are captured by functional tests above, nothing additional to do

## (Un)related regressions
1. Table loading state is not working anymore, we see the empty state
before table content
2. Filtering by Creator Tim Ap return empty results
3. Not possible to add Tasks / Notes / Files from show page

# Result

## New seeds that can be easily extended
<img width="1920" alt="image"
src="https://github.com/user-attachments/assets/d290d130-2a5f-44e6-b419-7e42a89eec4b"
/>

## -5k lines of code
## No more 'metadata' dataSource (we only have 'core)
## No more relationMetadata (I haven't drop the table yet it's not
referenced in the code anymore)
## We are ready to fix the 6 months lag between current API results and
our mocked tests
## No more bug on relation creation / deletion

---------

Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-06-10 16:45:27 +02:00
MarieandGitHub 264861e020 [permissions V2] Add integration tests on relations and objectRecord permissions (#12450)
In this PR

1. adding tests on relations and nested relations to make sure that if
any permission is missing, the query fails
2. adding tests on objectRecord permissions to make sure that
permissions granted or restricted by objectPermissions take precedence
on the role's allObjectRecords permissions
2025-06-10 16:38:38 +02:00
78ecb01c90 Fix camel case typo Orobject in twenty-orm files (#12491)
Was looking into the Twenty ORM files and caught a camelCase typo which
is `workspaceEntityOrobjectMetadataName` to
`workspaceEntityOrObjectMetadataName` in two files
1. twenty-orm.manager.ts
2. twenty-orm-global.manager.ts

Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-06-10 13:49:35 +00:00
02bd15d61f Website changes docs playground (#10413)
From #10376 (extracting website related changes to deploy them
separately, later)

---------

Co-authored-by: oliver <8559757+oliverqx@users.noreply.github.com>
2025-06-10 15:01:24 +02:00
GuillimandGitHub b74f6901b4 modal fix (#12514)
issue was the modal was closing itself due to onclickoutside while it
should have been excluded

fixes https://github.com/twentyhq/twenty/issues/12512
2025-06-10 14:44:25 +02:00
Lucas BordeauandGitHub f0f0d85380 Fixed sub-field filter dropdown content and icons (#12516)
This PR improves the sub-field selection UX in advanced filters.

- Now using the icon of the field instead of the field type
- Now using the label of the field instead of the field type
- Removed now useless constant ICON_NAME_BY_ANY_SUB_FIELD
- Now selects a default value (any or default sub-field for type) when
clicking on the field, instead of waiting for the user to select the
sub-field

Fixes https://github.com/twentyhq/core-team-issues/issues/1005
2025-06-10 14:00:12 +02:00
NaiferandGitHub 78d63a3fe8 fix(frontend):Prevent record type select dropdown from opening when viewing a workflow version (#12495)
Closes #12003 


https://github.com/user-attachments/assets/07561cf6-a45d-4f7e-815e-550421d1bd9f
2025-06-10 12:20:46 +02:00
MarieandGitHub 9cfabd81cb Fix missing New Note / New Task button (#12513)
New Note button was missing because of the wrong condition being applied
to display it
<img width="492" alt="Capture d’écran 2025-06-10 à 10 26 57"
src="https://github.com/user-attachments/assets/dafd10e3-b3a8-497c-9a00-c395f20cecbb"
/>
2025-06-10 09:12:41 +00:00
GuillimandGitHub 3cbd3427a1 chip-count-black-mode (#12505)
![image](https://github.com/user-attachments/assets/01b4576d-2409-4bf0-8fa7-bd39ad00ded5)

Add chip count display for black mode in participant chips.

Improves visual clarity for participant lists in calendar events.

Fix https://github.com/twentyhq/twenty/issues/12473
2025-06-10 10:03:04 +02:00
Baptiste DevessierandGitHub 7f19111e57 Stop forwarding the active prop for the TabButton component (#12501)
This error was triggered:

![CleanShot 2025-06-09 at 14 49
45@2x](https://github.com/user-attachments/assets/9cc02f99-aead-40ec-aec1-33a6f8a4b81f)
2025-06-09 16:12:30 +02:00
Abdul RahmanandGitHub 1f2c40af61 fix: prevent duplicate dropdowns in activity targets when editing in different contexts (#12462)
Closes #12361

### Changes Made

- In `ActivityTargetsInlineCell`, we now use different component
instance IDs based on context. This ensures that each instance of the
component (whether in right drawer or main view) has its own isolated
state, preventing state conflicts and duplicate dropdowns.
- The `MultipleRecordPicker` component now properly resets its state
when closed, preventing state leakage between instances.


https://github.com/user-attachments/assets/deb99687-a803-417e-a339-cab061026739
2025-06-09 15:20:13 +02:00
Ajay A AdsuleandGitHub da35a2f479 fix: trigger onClickOutside when click escape for closing the model a… (#12461)
Description:
Resolved a bug where pressing the Escape key did not clear the filter
chips when no filter value was present.
Added a call to onClickOutside inside the useScopedHotkeys hook to
ensure filter chips are removed when Escape is pressed and the dropdown
is open but empty.



https://github.com/user-attachments/assets/42ed35b0-f5a8-4d26-8407-fdd5e2cc4a42

fix #12319
2025-06-09 15:08:57 +02:00
ecf21774dd Fix workspace hydratation (#12452)
We must separate the concept of hydratation which happens at the request
level (take the token and pass auth/user context), from the concept of
authorization which happens at the query/endpoint/mutation level.

Previously, hydratation exemption happened at the operation name level
which is not correct because the operation name is meaningless and
optional. Still this gave an impression of security by enforcing a
blacklist. So in this PR we introduce linting rule that aim to achieve a
similar behavior, now every api method has to have a guard. That way if
and endpoint is not protected by AuthUserGuard or AuthWorspaceGuard,
then it has to be stated explicitly next to its code.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-09 14:14:32 +02:00
Félix MalfaitGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
322c8a1852 Upgrade to Node22 (#12488)
BlocknoteJS requires an ESM module where our server is CJS, this forced
us to pin the server-util version, which led us to force the resolution
of several packages, leading to bugs downstream.

From Node 22.12 Node supports requiring ESM modules (available from Node
22.0 with a flag). So I upgrade the module.
I picked Node 22 and not Node 23 or Node 24 because 22 is the LTS and we
don't plan to change node versions frequently.

If you remain on Node 18, things should still mostly work, except if you
edit a Rich Text field.

I also starting changing the default runtime for Serverless Functions
which isn't directly related. This means new serverless functions will
be created on Node 22, but we will still need another PR to migrate
existing serverless functions before September (end of support by AWS).

(In this PR I also remove the upgrade commands from 0.43 since they rely
on Blocknote and I didn't want to have to deal with this)

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-06-06 18:35:30 +02:00
Thomas TrompetteandGitHub 0188b66280 Add filters to search record action (#12481)
First PR to add filters to send records. Lot of work left, but I want to
split. I mainly want to validate the architecture there.


https://github.com/user-attachments/assets/63375a75-ba88-49df-8c12-5e3e58de5342

TODO in next PRs:
- fix design
- make filters reliable. Some composite fields are not implemented and
some fields like datetime do not work well
- improve typing
2025-06-06 12:29:53 +00:00
b85ea721e5 i18n - translations (#12478)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-05 21:01:38 +02:00
254a3eadb8 i18n - translations (#12477)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-05 20:57:07 +02:00
b2c57c5dcc Update billing page ctas (#12459)
## Before

![image](https://github.com/user-attachments/assets/95315651-8b04-4004-a6b6-8742ebcc6f9d)

## After
<img width="1056" alt="image"
src="https://github.com/user-attachments/assets/4a51b7c7-898b-485f-95e8-97911292f2b1"
/>
<img width="1299" alt="image"
src="https://github.com/user-attachments/assets/44e5e545-a660-455a-91be-3b139ccb9f30"
/>
<img width="1180" alt="image"
src="https://github.com/user-attachments/assets/0ca765a7-1d9a-473a-b7d2-c6f9b1a72417"
/>
<img width="963" alt="image"
src="https://github.com/user-attachments/assets/b620fd8a-61c9-4dd3-a3b1-e4ba940371e4"
/>
<img width="863" alt="image"
src="https://github.com/user-attachments/assets/a0d2dcb5-19e5-4f83-80d4-ad5a715f1e5f"
/>

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-06-05 20:56:55 +02:00
Lucas BordeauandGitHub c75f10bc33 Fix filter sub-field icons (#12456)
This PR fixes filter sub-field icons, with more relevant icons.

Fixes https://github.com/twentyhq/core-team-issues/issues/1006
2025-06-05 20:54:49 +02:00
Lucas BordeauandGitHub 7c898cd008 Fix filter and sort chips in view bar (#12455)
This PR fixes the filter and sort chips in the view bar.

Fixes https://github.com/twentyhq/core-team-issues/issues/1002
Fixes https://github.com/twentyhq/core-team-issues/issues/1003
2025-06-05 20:53:47 +02:00
Lucas BordeauandGitHub 276f1796cc Implemented dropdown menu section label in filter and sort (#12453)
This PR implements a new component `DropdownMenuSectionLabel`, to be
used for indicating visible and hidden fields in the multiple dropdowns
that use those two sections.

After : 

<img width="247" alt="Capture d’écran 2025-06-04 à 12 49 42"
src="https://github.com/user-attachments/assets/759c48ca-c54d-4921-bea6-cbfe7a2d244d"
/>
<img width="252" alt="Capture d’écran 2025-06-04 à 12 49 20"
src="https://github.com/user-attachments/assets/72cd63d0-e5d6-4000-897d-c16efd8396c9"
/>
<img width="359" alt="Capture d’écran 2025-06-04 à 12 48 44"
src="https://github.com/user-attachments/assets/d7c41039-dc15-46d7-be89-33a39e226fb2"
/>

In this PR we also fix the scrolling behavior of those two sections so
that it is more natural. The height mechanism will be properly
refactored by this issue :
https://github.com/twentyhq/twenty/issues/11766, in the mean time this
temporary modification is working :


https://github.com/user-attachments/assets/c7ddb424-66b9-41e3-a6a8-a29ece09d62e

Some components that weren't used are also removed :
`AdvancedFilterDropdownFieldSelectMenu`,
`AdvancedFilterDropdownFieldSelectMenuItem` and
`AdvancedFilterDropdownSubFieldSelectMenu`

Fixes https://github.com/twentyhq/core-team-issues/issues/1000
2025-06-05 20:50:12 +02:00
Karuna TataandGitHub 26bd16a2cb fix: favicon when workspace icon is removed (#12451)
closes #12304
2025-06-05 20:46:08 +02:00
6f156a69b0 feat: new tab list (#12384)
closes #9904

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-05 20:44:21 +02:00
a86b5fb9b2 fix(frontend): prevent command menu reopening when clicking the same field (#12390)
ressolve #12205
This PR fixes the issue where the record in the command menu was
reopening when clicking the same field again.

https://github.com/user-attachments/assets/52da7b3f-4704-4a9c-8fc4-29534568b0c0




- Added recordId to cells so it can be accessed when
useListenClickOutside is triggered, and compared the previous recordId
with the new one to prevent closing the command menu for the same
record.

- When the field is clicked, we compare the lastRecordId with the new
recordId inside the openRecordInCommandMenu function to avoid reopening
the menu unnecessarily.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-05 20:32:46 +02:00
GuillimandGitHub 76860207ca Index-back-into-the-game (#12466)
# Indexes

### TLDR:
 Putting indexes back, except relation ones

### Details:
- Added index synchronization logic back (it was removed previously in
https://github.com/twentyhq/twenty/commit/45d4845b266119ef6f2bc8005bf1cc3b542a8f42)
in the sync-metadata service.

- for unique inedexes, a command will create unicity again by handling
duplicates that were cretated since the
https://github.com/twentyhq/twenty/commit/45d4845b266119ef6f2bc8005bf1cc3b542a8f42
was triggered
2025-06-05 20:01:37 +02:00
GuillimandGitHub 61237916fd Fix Integration test (#12470)
# Integration test failing

- fix the local run by renaming folder in the jest configuration.
Otherwise "clickhouse" tests were failing

- falsy test introduced 2 days ago in
https://github.com/twentyhq/twenty/pull/12271/files
2025-06-05 19:57:53 +02:00
Raphaël BosiandGitHub 2f89b36693 Fix ClientConfigProviderEffect infite loop (#12472)
Fixes an infinite loop introduced by #12371

An infinite loop was triggered when there was an error when fetching the
client config.
Cause of the bug: `isLoadedOnce` wasn't set to true when catching an
error in `useClientConfig`.

This effect then created an infinite loop inside
`ClientConfigProviderEffect` because `fetchClientConfig` updated
`clientConfigApiStatus.isLoading` but not `isLoadedOnce`.

```typescript
useEffect(() => {
    if (
      !clientConfigApiStatus.isLoadedOnce &&
      !clientConfigApiStatus.isLoading
    ) {
      fetchClientConfig();
    }
  }, [
    clientConfigApiStatus.isLoadedOnce,
    clientConfigApiStatus.isLoading,
    fetchClientConfig,
  ]);
```
2025-06-05 19:38:10 +02:00
Charles BochetandGitHub 9598a4dda2 Fix infinite loop on table load (#12474)
This was a tough one:
- we should avoid updating lazy findManyRecords function with
onCompleted callback, this is prone to infinite loops
2025-06-05 19:37:23 +02:00
39d3c6a218 i18n - translations (#12468)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-05 16:01:19 +02:00
3f30964523 [FE] handle restricted objects 2 (#12437)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-05 15:49:22 +02:00
ad804ebecd i18n - translations (#12465)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-05 14:22:43 +02:00
EtienneandGitHub 2dd8b9af10 add field validation + add other subfields import (#12444)
- Add some subfield imports : primaryLinkLabel / primaryPhoneCallingCode
/ additionalPhones
- Add validation rules for field and subfield

Comments
- Check other validations that can be done
- Refacto on subFieldKey ("...Label")
- Add global tests on validation step -
[issue](https://github.com/twentyhq/core-team-issues/issues/1067)

closes https://github.com/twentyhq/core-team-issues/issues/903 
closes https://github.com/twentyhq/core-team-issues/issues/910
closes https://github.com/twentyhq/core-team-issues/issues/985
closes https://github.com/twentyhq/core-team-issues/issues/904
2025-06-05 12:12:24 +00:00
Félix MalfaitandGitHub b481abbb0f Begin refactoring AI module (#12464)
Cleaning up to prepare for a few tests
2025-06-05 12:28:42 +02:00
a67435f840 i18n - translations (#12458)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-04 15:24:58 +02:00
+12
Abdul RahmanGitHubFélix MalfaitFélix Malfaitgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>MarieCharles BochetJordan ChalupkaCharles BochetThomas TrompetteGuillimRaphaël Bosijaspass04martmullThomas des FrancsEtiennegithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>github-actionsWeikoMatt DvertolaguillimZeroday BYTE
63c9af54f5 feat: implement TS vector search filter (#12392)
Closes #12427 

This PR introduces a comprehensive search filter system that enhances
the application's data filtering capabilities. At its core, the
implementation leverages a custom useSearchFilter hook that manages
search state and operations, providing a consistent search experience
across different components. The search functionality is optimized for
performance through debounced operations (500ms) and efficient state
management using Recoil. Users can trigger search through keyboard
shortcuts (Ctrl/Cmd + F) or UI interactions, with the system maintaining
search state persistence and providing clear visual feedback. The
implementation integrates seamlessly with the existing record filtering
system, view bar components, and advanced filter system, while ensuring
good performance through optimized re-renders and component state
isolation.


https://github.com/user-attachments/assets/12936189-fba8-44b3-a30c-d8cb6d6bd514

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Marie <51697796+ijreilly@users.noreply.github.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Jordan Chalupka <9794216+jordan-chalupka@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
Co-authored-by: Guillim <guillim@users.noreply.github.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: jaspass04 <147055860+jaspass04@users.noreply.github.com>
Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: Thomas des Francs <tdesfrancs@gmail.com>
Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: Matt Dvertola <64113801+mdvertola@users.noreply.github.com>
Co-authored-by: guillim <guigloo@msn.com>
Co-authored-by: Zeroday BYTE <github@zerodaysec.org>
2025-06-04 15:07:52 +02:00
Raphaël BosiandGitHub 7046965496 Fix dropdown z index (#12442)
Fixes https://github.com/twentyhq/twenty/issues/11942

This PR creates two different dropdown z indexes, one for normal
dropdowns, and one for the dropdowns inside modals.
2025-06-04 11:14:56 +02:00
Félix MalfaitandGitHub f7e2c1c627 Fix metadata mocks loaded during login issue (#12446)
If you tried to add a delay in `refreshObjectMetadataItems` like this`
await new Promise((resolve) => setTimeout(resolve, 5000))`, then this
caused an issue where the user was redirected to his workspace because
the metadata was not loaded.

This happened because I had removed the call to fetch metadata
explicitly in useAuth (instead relying on the effect to fetch it because
it was done twice). I had removed it because this was causing issues in
the onboarding process where /metadata was called too early and then
cached with the wrong reply.

The correct fix is instead to change the fetch policy to `network only`
to stop hiding re-renders to the object metadata effect with Apollo's
cache mechanism. Now the [] reply isn't cached in the onboarding, the
metadata effect is only triggered during initial page load and refresh
should be called explicitely.

I also noticed a bug on the server side where sometimes the frontend was
passing a token for public requests (login token exchange request,
public domain data request). I removed the check so that the backend
completely ignores the token when it's passed on public request. The
downside is that we're losing information for logs (who did that request
to a public endpoint), but it doesn't make much sense to throw
authentication errors on that endpoint imo. Probably a better root-cause
fix would be to understand why a token is still passed on the frontend,
but that would require more investigation — the bug happened when I was
signing up and redirected from the app.xxx domain to the workspace
domain
2025-06-04 11:01:30 +02:00
martmullandGitHub e227c0443a Fix workflow diagram success edges (#12439)
## Before
<img width="492" alt="image"
src="https://github.com/user-attachments/assets/6c85baea-3b58-4196-87ab-dcc7bcb4e5ca"
/>

## After
<img width="477" alt="image"
src="https://github.com/user-attachments/assets/0428f1f0-ef73-4fa1-b778-d1536a8b84e6"
/>
2025-06-03 16:51:04 +02:00
martmullandGitHub 0e68602030 Fix function input computation in workflow code step (#12440)
As title
Fix consist by awaiting for getFunctionInputFromSourceCode response
2025-06-03 16:50:46 +02:00
nitinandGitHub 7ab3d19e64 update setup docs - config variables (#12370)
closes https://github.com/twentyhq/core-team-issues/issues/958
2025-06-03 16:24:28 +02:00
martmullandGitHub cb010d90fe 998 workflow restore (#12417)
Add a post hook to restore workflow sub-entities
2025-06-03 15:28:43 +02:00
a943f9cf36 Improve documentation by adding multiple emails support (#12435)
Follow up on https://github.com/twentyhq/twenty/pull/12368

---------

Co-authored-by: Thomas des Francs <tdesfrancs@gmail.com>
2025-06-03 13:07:06 +00:00
eb7556e333 Fix: multi-select default values validation (#12271)
https://github.com/user-attachments/assets/3bea63cc-b098-4252-8787-fc6263f01e8d


Closes #12277

---------

Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-03 15:01:58 +02:00
eed9125945 Improved participant matching with additional emails support (#12368)
# Improved participant matching with additional emails support

Closes #8991 

This PR extends the participant matching system to support additional
emails in addition to primary emails for both calendar events and
messages. Previously, the system only matched participants based on
primary emails, missing matches with secondary email addresses.

- Contact creation now consider both primary and additional emails when
checking for existing contacts
- Calendar and message participant listeners now handle both primary and
additional email changes
- Added tests

## To test this PR:

Check that:
- Primary emails take precedence over additional emails in matching
- Case-insensitive email comparisons work correctly
- A contact is not created if a person already exists with the email as
its additional email
- Event listeners handle both creation and update scenarios
- Matching and unmatching logic works for complex email change scenarios
- When unmatching after a change in a primary or secondary email, events
and messages should be rematched if another person has this email as its
primary or secondary email.

---------

Co-authored-by: guillim <guigloo@msn.com>
2025-06-03 14:36:56 +02:00
GuillimandGitHub 179365b4bc making sure status is "ONGOING" (#12432)
Fixes #12428
2025-06-03 14:36:06 +02:00
GuillimandGitHub a8eacd30a1 better logging of calendar failures (#12431)
better logging to troubleshoot calendar events failure :

```
[Nest] 1  -  [GoogleCalendarGetEventsService] Error: internal_failure
```
2025-06-03 12:23:36 +00:00
278a7baf5e Feat: add support for day-first and year-first date formats (DD/MM/YYYY, YYYY/MM/DD) (#12333)
Closes #12152 



https://github.com/user-attachments/assets/53640777-578f-4de8-a1f8-52d409a7582d

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-06-03 14:12:01 +02:00
Raphaël BosiandGitHub 70cc3e75fe Eliminate unnecessary API calls when persisting field (#12429)
Fixes #10177

Modified `usePersistField` to check for deep equality between the value
to persist and the current record store value before sending an update
query.
2025-06-03 12:20:57 +02:00
Charles BochetandGitHub ece2784ed7 Fix linter post merge (#12430) 2025-06-03 11:51:49 +02:00
Zeroday BYTEandGitHub 4aae6bae1c fix(packages): shell command built from environment values (#12386)
https://github.com/twentyhq/twenty/blob/b7473371b3fda51de96241533dc7d56856134f72/packages/twenty-server/src/engine/core-modules/serverless/commands/add-packages.command.ts#L6-L6


https://github.com/twentyhq/twenty/blob/b7473371b3fda51de96241533dc7d56856134f72/packages/twenty-server/src/engine/core-modules/serverless/commands/add-packages.command.ts#L10-L10


https://github.com/twentyhq/twenty/blob/b7473371b3fda51de96241533dc7d56856134f72/packages/twenty-server/src/engine/core-modules/serverless/commands/add-packages.command.ts#L79-L79

Fix the issue should avoid dynamically constructing the shell command.
Instead, we can use `execFile` or `execFileSync`, which allows us to
pass arguments as an array, avoiding shell interpretation of special
characters. This ensures that the `folderPath` is treated as a literal
argument and not subject to command injection.

Specifically:
1. Replace the use of `execPromise` with `execFilePromise` (a
promisified version of `execFile`).
2. Modify the `addToGit` method to pass the `folderPath` as an argument
to `git add` instead of interpolating it into the command string.



---
2025-06-03 11:35:31 +02:00
f60b704feb #12336 adding gmail email sync error handling (#12383)
I believe that some emails with invalid characters are breaking the sync
process.

this PR attempts to create a "safeParseAddress" function. Hopefully this
will change current behavior of a single email breaking the entire sync
process to the sync process "skipping" an invalid email address and
continuing on.

I opened this because of issues explained in #12336

---------

Co-authored-by: guillim <guigloo@msn.com>
2025-06-03 11:17:48 +02:00
GuillimandGitHub 7617dd76aa removing webhooks failed logs (#12425)
As discussed with @martmull , we remove the logs in order to keep our
logs (for cloud users, Grafana) clean.

Comes in the effort of cleaning logs to faster troubleshoot, see below
the noise it creates
<img width="1345" alt="Screenshot_2025-06-02_at_13 51 40"
src="https://github.com/user-attachments/assets/70ecdb2d-f37e-446b-8df4-a6a8fb165a9a"
/>

related to [this
issue](https://github.com/twentyhq/core-team-issues/issues/1059)
2025-06-03 09:01:01 +00:00
Félix MalfaitandGitHub e1395b00e3 Remove useless indexes (#12422)
As discussed with @charlesBochet - those indexes don't add any value
2025-06-03 10:03:19 +02:00
Félix MalfaitandGitHub 8c2da395bb Fix Invalid input in Track Analytics (#12421)
Fix #12231
2025-06-03 08:50:44 +02:00
c4ffd38435 i18n - translations (#12419)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-02 20:39:09 +02:00
WeikoandGitHub 8e710004ba Role page various fixes 2 (#12416)
- Fix: AvatarURL signedPath for workspace members were not consistent
when queried multiple times and it was causing the frontend to wrongly
interpret this as a change in the deepEqual condition
- Use SaveAndCancel button to be consistent with data model page
- When applying all object permission changes, a "smarter" logic applies
and removes all permissions if read is unchecked for example
- Hide settings permissions when Settings All Access is toggled
2025-06-02 20:24:53 +02:00
MarieandGitHub e1a7fa3e5d [permissions] Override workspaceDatasource.createQueryBuilder (#12415)
In the frame of https://github.com/twentyhq/core-team-issues/issues/924

- Rename dataSource -> workspaceDataSource when relevant to ease
understandability
- override workspaceDataSource.createQueryBuilder, because we don't want
developers to use it directly since it does not run permission checks at
this level. Indeed, we cannot do so because 1) datasources are shared
between roles so we would need to re-think its implementation to make
that possible, while for now we never call
workspaceDatasource.createQueryBuilder in our codebase 2)
workspaceEntityManager.createQueryBuilder, that we have overriden with
permission checks, then performs a call to
workspaceDataSource.createQueryBuilder so that would make two permission
checks.
2025-06-02 16:37:23 +00:00
5ea3a3c887 i18n - translations (#12418)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-06-02 18:08:34 +02:00
Thomas TrompetteandGitHub a508f4a4fb Add empty message for form actions (#12414)
<img width="503" alt="Capture d’écran 2025-06-02 à 15 55 36"
src="https://github.com/user-attachments/assets/9b3f60ae-7a13-45f8-aa87-ba32211e832f"
/>
2025-06-02 16:04:39 +00:00
EtienneandGitHub e71aef5a3a Import v2 - add label for subfield in csv export (#12355)
To test : Export companies record - "Domain Name PrimaryLinkUrl" >>
"Domain Name / Link URL"

closes https://github.com/twentyhq/core-team-issues/issues/907
2025-06-02 17:21:44 +02:00
MarieandGitHub dc205370df Forbid upsert of objectPermissions on system objects (#12382)
Closes https://github.com/twentyhq/core-team-issues/issues/865
2025-06-02 15:03:37 +00:00
e13d83b660 Seed update - Replaced Qonto by Anthropic (#12340)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-02 16:42:53 +02:00
f81d396413 Fixed Actor Icon Size & color (#12373)
![CleanShot 2025-05-29 at 11 54
26@2x](https://github.com/user-attachments/assets/61182699-357e-45ad-a625-c66445727e3b)

1. was 16px instead of 14px like 2.
2. was 14px – font color had low contrast – height was 16px instead of
14px

Couldn't test if 1 was fixed as didn't have a local email server.

2. is fixed:

![CleanShot 2025-05-29 at 11 56
26@2x](https://github.com/user-attachments/assets/38cccf84-e36e-4a3e-80c9-43ddac46f2f9)

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-06-02 16:36:47 +02:00
MarieandGitHub e723d64bc4 Add tests on granular settings permissions (#12403)
Closes https://github.com/twentyhq/core-team-issues/issues/605

Actually settingsPermissions checks were already implemented, but we had
no tests on them.

In the ticket we had mentioned 
_TO DO: in pemissions.service we should stop calling
userRoleService.getRolesByUserWorkspaces and call
getRoleIdForUserWorkspace instead which relies on the cache._
But actually roleId is not enough for settings permissions because we
don't store them in the cache (unlien object records permissions - which
I think we had forgotten about when adding that TODO.), so we will still
need to make a db call to load the role's settingsPermissions. I think
it's better to make just one db call to get the role and
settingsPermissions from userWorkspaceId (as currently) than to make one
redis call to get roleId for userWorksapce then one db call to get role
and its settingsPermissions).
2025-06-02 16:16:57 +02:00
Charles BochetandGitHub 881b9d9e50 Fix stories chromatic (#12412)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/973df4a5-a12c-438c-87a8-3218e63d9998"
/>
2025-06-02 15:34:08 +02:00
Raphaël BosiandGitHub c7b8df428f Don't overwrite SELECT fields at draft (#12413)
Fixes https://github.com/twentyhq/twenty/issues/12328
2025-06-02 15:33:57 +02:00
GuillimandGitHub b80a270e9d adding new error codes to the temporary catch (#12366)
For microsoft, examples of errors from the logs:

<img width="1251" alt="Screenshot 2025-05-28 at 18 02 48"
src="https://github.com/user-attachments/assets/7de506b2-3e68-4ee5-907a-62fe6a0e2ba5"
/>


Fixes https://github.com/twentyhq/twenty/issues/12252
2025-06-02 15:15:49 +02:00
martmullandGitHub f48145c01b Fix edge x position (#12410)
## Before
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/59014e1f-8cf1-4a38-8cf7-675104fc8f3d"
/>

## After
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/93da4dbb-d0ed-417c-86f7-970a4e9858a4"
/>
2025-06-02 14:59:06 +02:00
GuillimandGitHub 5914a89df2 Catching temporary errors in microsft batch calls (#12409)
# 🐛 Improve Microsoft Graph API Temporary Error Handling on PARSE method

fixes Sentry error
<img width="886" alt="Screenshot 2025-06-02 at 14 39 19"
src="https://github.com/user-attachments/assets/117a2601-4bad-48a2-8112-2bb682559b15"
/>


### What:
Enhances error handling for Microsoft Graph API batch calls 
### How: by treating HTTP 503 (Service Unavailable) as temporary errors
alongside existing 429 (Rate Limit) handling.

### Additional: 
improving logging


Fixes https://github.com/twentyhq/twenty/issues/12257
2025-06-02 12:46:36 +00:00
jaspass04andGitHub 2bf11d425a Reorder Action Menu Items for Better UX (#12408)
## Quick Overview
This PR addresses the issue of reordering the action menu items to
improve user experience. The changes ensure that the "Import records"
and "Export view" actions are placed next to each other, with "Import
records" appearing before "Export view". This sequence is more intuitive
and aligns with common user expectations.

## Changes Made:
Adjusted the position of "Import records" to be before "Export view".
Ensured the sequence is now: 1. Import, 2. Export, 3. Delete.

## Impact:
Improved user experience by providing a more logical order of actions.
Aligned with user expectations for common data operations.


**Before:**

![image](https://github.com/user-attachments/assets/59c8a586-9dbf-4774-a9f3-492e1577a5f5)

**After:**
<img width="438" alt="Screenshot 2025-06-02 at 2 03 01 PM"
src="https://github.com/user-attachments/assets/d38d95f0-1ae4-4b78-976b-837ee5df0c9e"
/>
Ensured no regressions in existing functionality.
2025-06-02 13:54:29 +02:00
Raphaël BosiandGitHub f0d85ea868 Fix auth modal closing hotkey scopes (#12407)
The auth modal is a particular modal because it is the only one that is
opened in an effect (because its opening depends on the location).

After the hotkey scopes and the modal refactoring, we are now force to
call `openModal` and `closeModal` to open and close the modals. Here,
the `closeModal` wasn't called, but the modal was simply unmounted. The
global hotkeys were then disabled because the modal was still in the
focus stack.

Fixes
[#1052](https://github.com/twentyhq/core-team-issues/issues/1052#event-17916955590)
2025-06-02 13:42:08 +02:00
GuillimandGitHub 2001041a48 Google-scopes-handling (#12362)
# Summary

Enhanced the Google OAuth flow to better handle missing permissions and
improved user experience by redirecting to settings/account page.


## Changes
- Added new google-apis-scopes.ts service for better scope management
- Updated Google APIs auth controller for better flow control
- New tests for this logic

## User request
From @bonapara email test and need to better handle user flow during the
connect email flow

Before :
<img width="574" alt="Screenshot 2025-05-28 at 17 58 59"
src="https://github.com/user-attachments/assets/fd54625b-e211-4b2f-b76a-48bcb08b5222"
/>

After : 
<img width="1143" alt="Screenshot 2025-05-28 at 16 29 05"
src="https://github.com/user-attachments/assets/8f3d1f2c-9e02-4d25-b949-fe2b20f048f4"
/>

## Reference :
For google specialities, I added this link in the `export const
getGoogleApisOauthScopes` in order to keep that in mind

https://developers.google.com/identity/protocols/oauth2/scopes
2025-06-02 12:28:55 +02:00
Thomas TrompetteandGitHub 4e410db983 Emit company created event (#12404)
Fixes https://github.com/twentyhq/twenty/issues/12337

When importing emails, matched companies are added, but no event is
triggered. Which means that workflows are not triggered. Adding the
event.

To test:
- create a workflow that listens to company creation
- import emails
- make sure workflow has been triggered
2025-06-02 12:16:16 +02:00
Charles Bochet 5339f86f03 Fix linter on server commands 2025-06-02 12:12:13 +02:00
Jordan ChalupkaandGitHub 1d197f2dc8 skip metadata._typeorm_migrations if they don't exist (#12398)
I am seeing an issue where this migrations fails because the
`metadata._typeorm_migrations` table does not exist.

```pgsql
copy _typeorm_migrations from metadata to core
query failed: SELECT * FROM metadata._typeorm_migrations ORDER BY id ASC
error: error: relation "metadata._typeorm_migrations" does not exist
[Nest] 430  - 06/01/2025, 10:22:35 PM   ERROR [CopyTypeormMigrationsCommand] Failed to copy migrations: relation "metadata._typeorm_migrations" does not exist
[Nest] 430  - 06/01/2025, 10:22:35 PM   ERROR [CopyTypeormMigrationsCommand] undefined
[Nest] 430  - 06/01/2025, 10:22:35 PM   ERROR [DatabaseMigrationService] Error running database migrations:
[Nest] 430  - 06/01/2025, 10:22:35 PM   ERROR [DatabaseMigrationService] QueryFailedError: relation "metadata._typeorm_migrations" does not exist
[Nest] 430  - 06/01/2025, 10:22:35 PM   ERROR [UpgradeCommand] Command failed
[Nest] 430  - 06/01/2025, 10:22:35 PM   ERROR [UpgradeCommand] undefined
[Nest] 430  - 06/01/2025, 10:22:35 PM     LOG [UpgradeCommand] Command completed!
[Nest] 430  - 06/01/2025, 10:22:35 PM   ERROR [QueryFailedError] relation "metadata._typeorm_migrations" does not exist
```

I _think_ this table is not meant to exist anymore - which means that
anyone who is onboarding into the project will run into an issue unless
we handle the case where the table doesn't exist.

We need to handle both the existing case and the non existing case to
support people who _do_ have metadata._typeorm_migrations` to migrate.
2025-06-02 12:11:30 +02:00
Charles BochetandGitHub bf3ad475f6 Fix CI lint server (#12406)
As per title
2025-06-02 12:07:51 +02:00
MarieGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
9706f0df13 [permissions] Remove raw queries and restrict its usage (#12360)
Closes https://github.com/twentyhq/core-team-issues/issues/748

In the frame of the work on permissions we

- remove all raw queries possible to use repositories instead
- forbid usage workspaceDataSource.executeRawQueries()
- restrict usage of workspaceDataSource.query() to force developers to
pass on shouldBypassPermissionChecks to use it.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-06-02 10:53:51 +02:00
Félix MalfaitandGitHub 1ef7b7a474 Add indices on frequent queries (#12401)
Fixes #12165

Also changed the index naming convention because some were not properly
name and would have caused conflicts in the long run
2025-06-02 09:55:45 +02:00
Félix MalfaitandGitHub f6bfec882a Improve lazy loading (#12393)
Creating manual chunk was a bad idea, we should always solve lazy
loading problem at the source instance.

Setting a 4.5MB for the index bundle size, CI will fail if we go above.

There is still a lot of room for optimizations!
- More agressive lazy loading (e.g. xyflow and tiptap are still loaded
in index!)
- Add a  prefetch mechanism
- Add stronger CI checks to make sure libraries we've set asides are not
added back
- Fix AllIcons component with does not work as intended (loaded on
initial load)
2025-06-01 09:33:16 +02:00
Félix MalfaitandGitHub c74d7fe986 Fix hotkey scope in settings (#12387)
Too many conflicts on hotkey scopes (e.g. we still had the issue on the
graphql playground). Let's disable all shortcuts in settings.
2025-05-30 16:45:33 +02:00
c7139cbc84 feat: Add TS vector field filters support (#12376)
# Implementation Details
- Added support for 5 operators: `contains`, `containsAny`,
`containsAll`, `matches`, and `fuzzy`
- Works on any field of type `TS_VECTOR`
- Added PostgreSQL `pg_trgm` extension for fuzzy search functionality.
The extension provides the `similarity()` function needed for text
similarity searches.
- Not implemented in GraphQL

## Tradeoffs & Decisions
1. **Fuzzy Search Performance**: Using `pg_trgm` for fuzzy search is
more accurate but slower than simple text matching. We might want to add
a similarity threshold parameter in the future to control the tradeoff
between accuracy and performance.

2. **Operator Naming**: Chose `contains`/`containsAny`/`containsAll` to
be consistent with existing filter operators, though they might be less
intuitive than `search`/`searchAny`/`searchAll`.

## Demo


https://github.com/user-attachments/assets/790fc3ed-a188-4b49-864f-996a37481d99

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-30 15:54:50 +02:00
b7473371b3 fix(client-config): set isLoaded to false on API status update (#12371)
Attempt at #12289 (edit Félix: removed fix keyword since I don't think
it fixes it)

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-30 14:44:31 +02:00
Lucas BordeauandGitHub 35a4b07bc2 Fixed non advanced filter creation from table header dropdown (#12369)
This PR fixes a edge case where the user tries to create a non-advanced
filter that already exists in advanced filters, from the table header
drodpown.

This was because the hook that handles the creation was checking for
duplicate filters but without discerning between advanced and
non-advanced, and we want to be able to create non-advanced filters no
matter what we have in advanced filters.

Fixes https://github.com/twentyhq/twenty/issues/12316
2025-05-30 12:16:55 +02:00
4dea441168 i18n - translations (#12378)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-30 08:39:09 +02:00
da00dee8a1 Fix settings navigation active state for sub-pages (#12318)
Changes the default behavior for settings navigation items to stay
active when navigating to sub-pages.

**Problem:**
- Navigation items like "Data Model" and "Webhooks" were not staying
highlighted when navigating to detail pages
- This was because `matchSubPages` defaulted to requiring exact path
matches

**Solution:**
- Updated logic to make sub-page matching the default behavior (`end:
item.matchSubPages === false`)
- Only "Accounts" explicitly sets `matchSubPages: false` for its custom
sub-item navigation
- Removed redundant `matchSubPages: true` declarations throughout the
codebase

**URL Changes:** -- checked with @Bonapara 
- `/settings/workspace` → `/settings/general`
- `/settings/workspace-members` → `/settings/members`
- `/settings/api-keys` → `/settings/apis`
- `/settings/developers/webhooks` → `/settings/webhooks`

before: 


https://github.com/user-attachments/assets/56b94a49-9c31-4bb5-9875-ec24f4bc4d1e

after:


https://github.com/user-attachments/assets/38742599-c045-44d1-8020-56f3eacca779

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-05-30 08:19:20 +02:00
dc0401edb5 Fixed kanban filter on kanban field metadata item (#12367)
This PR fixes an edge case where we couldn't apply a filter on the field
metadata item that is used by a kanban.

As this has already been fixed for tables with groups, this PR just uses
the same technique.

Fixes https://github.com/twentyhq/twenty/issues/12311

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-05-29 14:40:02 +02:00
Félix MalfaitandGitHub 4485e8e3db Update enums to be all caps (#12372)
- Make custom domain public (remove from lab)
- Use ALL_CAPS definition for enums
2025-05-29 14:08:36 +02:00
76d0be7f81 Fix members table column alignment (#12298)
Fixes: #12287 


![image](https://github.com/user-attachments/assets/4f8e8c9e-cf0a-4fa8-b129-087c29a8fd94)

---------

Co-authored-by: Divyanshu Lohani <DivyanshuLohani@users.noreply.github.com>
Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-05-28 17:29:07 +00:00
EtienneandGitHub 081376f594 Onboarding - add nextPath logic after email verification (#12342)
Context :
Plan choice [on pricing page on website](https://twenty.com/pricing)
should redirect you the right plan on app /plan-required page (after
sign in), thanks to query parameters and BillingCheckoutSessionState
sync.
With email verification, an other session starts at CTA click in
verification email. Initial BillingCheckoutSessionState is lost and user
can't submit to the plan he choose.

Solution : 
Pass a nextPath query parameter in email verification link

To test : 
- Modify .env to add IS_BILLING_ENABLED (+ reset db + sync billing) +
IS_EMAIL_VERIFICATION_REQUIRED
- Start test from this page
http://app.localhost:3001/welcome?billingCheckoutSession={%22plan%22:%22ENTERPRISE%22,%22interval%22:%22Year%22,%22requirePaymentMethod%22:true}
- After verification, check you arrive on /plan-required page with
Enterprise plan on a yearly interval (default is Pro/monthly).

closes https://github.com/twentyhq/twenty/issues/12288
2025-05-28 17:20:31 +00:00
martmullandGitHub 9eeb50cb14 Add relations in workflow action fields (#12359) 2025-05-28 18:32:24 +02:00
Baptiste DevessierandGitHub 1115f6fc57 Automatically open pending form nodes in the side panel (#12332)
- Keep the side panel open when submitting a pending form node if the
history isn't empty
- Prevent the same pending Form step from being automatically opened
several times
- Prevent duplicated views of the same pending form in the side panel

> [!WARNING]
Switching from the side panel view to the full-screen view isn't robust,
and I used a hack to make one use case work here. We'll have to improve
that part later.

## Before


https://github.com/user-attachments/assets/0f830e87-7681-49e9-acc8-a08178f631a2

## After


https://github.com/user-attachments/assets/bfd742d6-e38e-4981-a93b-8e895d3aa38a
2025-05-28 18:17:22 +02:00
Thomas TrompetteandGitHub b90cb3e1f9 Add filter fields on update record trigger (#12354)
Fixes https://github.com/twentyhq/core-team-issues/issues/928

<img width="503" alt="Capture d’écran 2025-05-28 à 15 04 08"
src="https://github.com/user-attachments/assets/b83ceced-4b3a-454c-83c1-1176f6836d96"
/>
2025-05-28 14:56:29 +00:00
Lucas BordeauandGitHub 630e4780b8 Fixed IconPicker infinite loop (#12356)
This PR fixes an infinite loop that was appearing on IconPicker, since
it was about setting and unsetting the hotkey scope, it wasn't really
noticeable.

The direct cause was using the mouse enter and mouse leave events to set
and unset the hotkey scope, without using a local state to prevent race
condition, so this PR just adds this local state.

Fixes https://github.com/twentyhq/twenty/issues/12344
2025-05-28 16:05:57 +02:00
Thomas TrompetteandGitHub 1144e210c5 Add fields to database event settings (#12331)
Backend part of https://github.com/twentyhq/core-team-issues/issues/928

- Add fields to database event settings
- If not set, match all automated triggers with the right event name
- If set, event needs at least one updated field listened to be treated
2025-05-28 14:58:35 +02:00
WeikoandGitHub ee00e2319e Fix missing objectRecordsPermissions from the API when permissions v2 is enabled (#12353) 2025-05-28 14:33:03 +02:00
Paul RastoinandGitHub 689e4ccfee Reverting broken filter from (#12352)
# Introdution
Reverting introduced bug by
https://github.com/twentyhq/twenty/pull/12082

We need to address the bug that was "fixed" by this in order to refresh
the recordFilters state, will have a look with @lucasbordeau 🙏
2025-05-28 12:20:51 +00:00
GuillimandGitHub 0a0fb976bf fixing : "message" : "Mail service not enabled" (#12349)
Fix Gmail API error handling for "Mail service not enabled" scenarios
Add proper await

Improves Gmail API error handling by properly detecting "Mail service
not enabled" errors and classifying them as INSUFFICIENT_PERMISSIONS
instead of TEMPORARY_ERROR


Fixes https://github.com/twentyhq/twenty/issues/12260
### Refernce :


https://stackoverflow.com/questions/31692720/gmail-api-returning-status-code-400-error-mail-service-not-enabled
2025-05-28 13:49:19 +02:00
Charles BochetandGitHub a4f190b913 Fix datasource race condition on migrate (#12350) 2025-05-28 13:31:02 +02:00
martmullandGitHub 69831b17ff Signed file follow up (#12347) 2025-05-28 13:02:27 +02:00
Félix MalfaitandGitHub d4fac6793a Left menu and chip links (#12294)
Small optimization for faster loading (gaining ~80ms - average time of a
click)

It might seem a little over-engineered but there are a lot of edge cases
and I couldn't find a simpler solution

I also tried to tackle Link Chips but it's more complex so this will be
for another PR
2025-05-28 12:32:49 +02:00
97d4ec96af Fix view filter update and deletion propagation (#12082)
# Introduction

Diff description: ~500 tests and +500 additions

close https://github.com/twentyhq/core-team-issues/issues/731

## What has been done here
In a nutshell on a field metadata type ( `SELECT MULTI_SELECT` ) update,
we will be browsing all `ViewFilters` in a post hook searching for some
referencing related updated `fieldMetadata` select. In order to update
or delete the `viewFilter` depending on the associated mutations.

## How to test:
- Add FieldMetadata `SELECT | MULTI_SELECT` to an existing or a new
`objectMetadata`
- Create a filtered view on created `fieldMetadata` with any options you
would like
- Remove some options ( in the best of the world some that are selected
by the filter ) from the `fieldMetadata` settings page
- Go back to the filtered view, removed or updated options should have
been hydrated in the `displayValue` and the filtered data should make
sense

## All filtered options are deleted edge case
If an update implies that a viewFilter does not have any existing
related options anymore, then we remove the viewFilter

## Testing
```sh 
PASS  test/integration/metadata/suites/field-metadata/update-one-field-metadata-related-record.integration-spec.ts (27 s)
  update-one-field-metadata-related-record
    SELECT
      ✓ should delete related view filter if all select field options got deleted (2799 ms)
      ✓ should update related multi selected options view filter (1244 ms)
      ✓ should update related solo selected option view filter (1235 ms)
      ✓ should handle partial deletion of selected options in view filter (1210 ms)
      ✓ should handle reordering of options while maintaining view filter values (1487 ms)
      ✓ should handle no changes update of options while maintaining existing view filter values (1174 ms)
      ✓ should handle adding new options while maintaining existing view filter (1174 ms)
      ✓ should update display value with options label if less than 3 options are selected (1249 ms)
      ✓ should throw error if view filter value is not a stringified JSON array (1300 ms)
    MULTI_SELECT
      ✓ should delete related view filter if all select field options got deleted (1127 ms)
      ✓ should update related multi selected options view filter (1215 ms)
      ✓ should update related solo selected option view filter (1404 ms)
      ✓ should handle partial deletion of selected options in view filter (1936 ms)
      ✓ should handle reordering of options while maintaining view filter values (1261 ms)
      ✓ should handle no changes update of options while maintaining existing view filter values (1831 ms)
      ✓ should handle adding new options while maintaining existing view filter (1610 ms)
      ✓ should update display value with options label if less than 3 options are selected (1889 ms)
      ✓ should throw error if view filter value is not a stringified JSON array (1365 ms)

Test Suites: 1 passed, 1 total
Tests:       18 passed, 18 total
Snapshots:   18 passed, 18 total
Time:        27.039 s
```
## Out of scope
- We should handle ViewFilter validation when extracting its definition
from the metadata
https://github.com/twentyhq/core-team-issues/issues/1009

## Concerns
- Are we able through the api to update an RATING fieldMetadata ? ( if
yes than that's an issue and we should handle RATING the same way than
for SELECT and MULTI_SELECT )
- It's not possible to group a view from a MULTI_SELECT field

The above points create a double nor a triple "lecture" to the post hook
effect:
- ViewGroup -> only SELECT
- VIewFilter -> only SELECT || MULTI_SELECT
- Rating nothing
I think we should determine the scope of all of that

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-28 10:22:28 +00:00
e63cd39a5b i18n - translations (#12341)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-28 10:50:02 +02:00
nitinandGitHub 1c64b7b072 feat: implement dynamic driver configuration + fix integration test log pollution (#12104)
### Primary Changes: Dynamic Driver Configuration
Refactors FileStorageService and EmailSenderService to support dynamic
driver configuration changes at runtime without requiring application
restarts.

**Key Architectural Change**: Instead of conditionally registering
drivers at build time based on configuration, we now **register all
possible drivers eagerly** and select the appropriate one at runtime.

### What Changed:
- **Before**: Modules conditionally registered only the configured
driver (e.g., only S3Driver if STORAGE_TYPE=S3)
- **After**: All drivers (LocalDriver, S3Driver, SmtpDriver,
LoggerDriver) are registered at startup
- **Runtime Selection**: Services dynamically choose and instantiate the
correct driver based on current configuration

### Secondary Fix: Integration Test Log Cleanup
Addresses ConfigStorageService error logs appearing in integration test
output by using injected LoggerService for consistent log handling.
2025-05-28 14:19:20 +05:30
d133055609 Fix Client Config async loading (#12308)
Fix ClientConfig async loading

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-28 10:40:20 +02:00
martmullandGitHub 196d8c97a4 Add relations in database event trigger output data (#11820)
## Done
- add relations in dropdown variables
- add relations in worklfow run inputs
- use objectMetadataMaps in workflow folder

## To do
- does not work with rest api calls, will be fixed after
https://github.com/twentyhq/twenty/pull/11349 is merged
- waiting for crud action relation fields
https://github.com/twentyhq/core-team-issues/issues/509
2025-05-27 20:46:15 +02:00
Lucas BordeauandGitHub 01b40e173b Refactored dropdown content and fixed all dropdown width bugs (#12334)
This PR refactors all the dropdown content wrapping mechanism across the
entire app.

It refactors the internals of the `Dropdown` component and introduces a
new generic `DropdownContent` component that is a generic wrapper used
for each dropdown.

## Why this PR ?

Because we’ve been experiencing continuous regressions for months on the
dropdown content width, with weird scrolling behaviors in some and not
in others, and every time a solution was found for a particular set of
dropdowns, it broke another set of dropdowns, which wasn’t noticed
because doing the QA of all dropdowns of the app is very difficult for
fixing an apparently small bug.

## Don’t we already have a `DropdownMenu` component ?

Indeed, this new `DropdownContent` is almost like `DropdownMenu` and
took inspiration from it but `DropdownContent` acts as a generic content
container that sets the width of the whole dropdown, whether we have a
menu or not.

## Why don’t we put it directly in Dropdown internals ?

Because the Dropdown component is using a complex logic with floating-ui
middleware to compute its position and size, and for this logic to work
correctly, it cannot be responsible for the “wanted” width of its
content, because the children components, which the dropdown is not
aware of, can request different widths after the dropdown has been
mounted.

A good example with multiple use cases inside the same dropdown can be
found in `AdvancedFilterDropdownFilterInput`

Thus, it is the responsibility of the content of the dropdown to
determine the width it wants to have.

## What is the difference with DropdownMenuItemsContainer ?

We can have multiple `DropdownMenuItemsContainer` in a dropdown,
alongside other components like `DropdownMenuSeparator` or
`DropdownMenuHeader`, and each of those components behaves differently
regarding to its width, paddings, etc. Therefore it is logical that the
`DropdownMenuItemsContainer` cannot be responsible for the whole
dropdown content width, and trying to do so has been the cause of many
regressions for months.

Now `DropdownMenuItemsContainer` is taking a width of `auto` by default,
which is the best to adapt to a parent which has a defined width.

## How do I set the width of my dropdown now ?

By passing a pixel width to the props `widthInPixels` of
`DropdownContent`, which only accepts numbers to avoid any confusion
with `auto` , `100%` or `160px` and other specific width variables.

The `dropdownWidth` props has been removed from `<Dropdown>` to avoid
any confusion.

Also the `DropdownMenuItemsContainer` is now using `auto` as its default
width to fill the available space inside `DropdownContent` .

It is highly recommended to use the enum `GenericDropdownContentWidt` to
define your width.

## Where to use this new `DropdownContent` component ?

There are two main use cases.

If the dropdown content is defined directly inline in the Dropdown
props, then it is recommended to use it here too.

On the other hand if the dropdown content is abstracted in another
component, it’s recommended to use this new component alongside the
others components like `DropdownMenuItemsContainer`.

A good rule of thumb is to place `DropdownContent` where
`DropdownMenuItemsContainer`, `DropdownMenuSearchInput`, etc. are
placed.

## What if I have a custom width ?

Just define a constant like `ICON_PICKER_DROPDOWN_CONTENT_WIDTH` and use
it with the props `widthInPixels` .

Otherwise there’s a `GenericDropdownContentWidth` enum. The default
value being `GenericDropdownContentWidth.Medium` (or 200px), which most
dropdowns use.

## QA 


Component | Comment
-- | --
AttachmentDropdown | Fixed overflowing (thanks to DropdownContent)
RecordIndexActionMenuDropdown |  
CommandMenuActionMenuDropdown |  
SupportDropdown | Fixed overflowing (thanks to DropdownContent)
MessageThreadSubscribersDropdownButton | Removed because unused
FavoriteFolderNavigationDrawerItemDropdown | Set width at Narrow
FavoriteFolderPicker |  
ViewPickerOptionDropdown |  
PageFavoriteFolderDropdown | Removed because unused
AdvancedFilterAddFilterRuleSelect |  
AdvancedFilterAddFilterRuleSelect |  
AdvancedFilterFieldSelectMenu |  
AdvancedFilterRecordFilterGroupOptionsDropdown |  
AdvancedFilterRecordFilterOperanceSelect | Set width at Narrow
AdvancedFilterLogicalOperatorDropdown | Set width at Narrow
AdvancedFilterRecordFilterOptionsDropdown |  
AdvancedFilterRootRecordFilterGroup | Fixed broken horizontal scrolling
behavior
AdvancedFilterSubFieldSelectMenu |  
AdvancedFilterDropdownFilterInput |  
ObjectFilterDropdownBooleanSelect |  
ObjectFilterDropdownCountrySelect | Fixed broken menu items container
ObjectFilterDropdownCurrencySelect | Set width to Large
ObjectFilterDropdownFilterInput |  
ObjectFilterDropdownOperandDropdown | Fixed width that was not fixed
ObjectFilterDropdownFilterInput | Fixed width that wasn’t the same for
EditableFilterChip
ObjectFilterDropdownOperandSelect | Refactored
ObjectOptionsDropdownRecordGroupFieldsContent | Added missing separator
ObjectOptionDropdownFieldsContent |  
ObjectOptionsDropdownHiddenFieldsContent |  
ObjectOptionsDropdownLayoutContent |  
ObjectOptionsDropdownLayoutOpenInContent |  
ObjectOptionsDropdownMenuContent |  
ObjectOptionsDropdownRecordGroupFieldsContent |  
ObjectOptionsDropdownRecordGroupsContent |  
ObjectOptionsDropdownRecordGroupSortContent |  
ObjectOptionsDropdownHiddenRecordGroupsContent | Removed unnecessary
DropdownMenuItemsContainer
RecordBoardColumnHeaderAggregateDropdown | Fixed overflowing (thanks to
DropdownContent)
RecordBoardColumnHeaderAggregateDropdownFieldsContent | Fixed
overflowing (thanks to DropdownContent)
RecordBoardColumnHeaderAggregateDropdownMenuContent | Fixed overflowing
(thanks to DropdownContent)
RecordBoardColumnHeaderAggregateDropdownOptionsContent | Fixed
overflowing (thanks to DropdownContent)
MultiItemFieldInput | Fixed overflowing (thanks to DropdownContent)
MultiItemFieldMenuItem |  
MultipleRecordPicker | Fixed overflowing (thanks to DropdownContent)
SingleRecordPicker |  
RecordTableColumnAggregateDropdownSubmenuContent |  
RecordTableColumnAggregateFooterMenuContent |  
RecordTableColumnHeadDropdownMenu | Fixed overflowing (thanks to
DropdownContent)
RecordTableHeaderPlusButtonContent |  
MultipleSelectDropdown | Broken width fixed
ObjectSortDropdownButton |  
RecordDetailRelationRecordsListItem |  
ConfigVariableDatabaseInput |  
ConfigVariableOptionsDropdownContent |  
SettingsObjectFieldActiveActionDropdown | Fixed overflowing (thanks to
DropdownContent)
SettingsObjectFieldDisabledActionDropdown | Set width at Narrow
SettingsObjectSummaryCard | Removed because unused
SettingsDataModelFieldSelectFormOptionRow |  
SettingsDataModelNewFieldBreadcrumbDropdown |  
SettingsObjectInactiveMenuDropDown |  
SettingsRoleAssignementWorkspaceMemberPickerDropdown |  
SettingsRolePermissionObjectLevelObjectPickerDropdownContent |  
SettingsSecurityApprovedAccessDomainRowDropdownMenu | Couldn’t test
SettingsSecuritySSORowDropdownMenu | Couldn’t test
SettingsAccountsRowDropdownMenu | Fixed overflowing (thanks to
DropdownContent)
SettingsIntegrationDatabaseConnectionSummaryCard | Couldn’t test
SettingsServerlessFunctionTablEnvironmentVariableTableRow | Deactivated
scope
MatchColumnSelectFieldSelectDropdownContent | Removed now unnecessary
width on DropdownMenuItemsContainer
MatchColumnSelectSubFieldSelectDropdownContent |  
SubMatchingSelectInput |  
CurrencyPickerDropdownSelect |  
IconPicker | Fixed overflowing (thanks to DropdownContent)
PhoneCountryPickerDropdownSelect |  
Select | Refactored to drilldown wanted width of content, in this case
it’s intended
ExpandedListDropdown |  
ShowPageAddButton | Removed because unused
MultiWorkspaceDropdownDefaultComponent |  
MultiWorkspaceDropdownThemesComponent |  
MultiWorkspaceDropdownWorkspacesListComponent |  
AdvancedFilterDropdownButton |  
EditableFilterChip |  
EditableFilterDropdownButton |  
UpdateViewButtonGroup |  
ViewBarFilterDropdown |  
ViewBarFilterDropdownFieldSelectMenu |  
ViewPickerContentCreateMode |  
ViewPickerContentEditMode |  
ViewPickerListContent |  
WorkflowEditTriggerDatabaseEventForm |  
WorkflowVariablesDropdownFieldItems |  
WorkflowVariablesDropdownObjectItems |  
WorkflowVariablesDropdownWorkflowStepItems |  
CommandMenuContextChipGroups |  
RecordBoardColumnDropdownMenu |  
MultiSelectInput |  
SelectInput |  
CustomSlashMenu |  
DropdownMenu | Removed and replaced by DropdownContent
OverlayContainer and around |  


<!-- notionvc: 1e23bdb8-2dda-4f8d-a64d-ecc829a768a2 -->

## Miscellaneous 

Side notes : 

- The `Select` component is now wrapping the `DropdownContent` because
it computes a dynamic width.
- The advanced filter dropdown has been fixed, it was broken when
resizing the window horizontally, we couldn’t scroll. This specific edge
case was taken into account when refactoring the whole dropdown content
system
- As discussed with Nitin, data-select-disable will probably be removed
entirely, so I let it as is, because right now it is not used by the
refactored d&d selection.
- Duplicate separators under DropdownMenuHeader have been removed.

Fixes : https://github.com/twentyhq/twenty/issues/12327
Fixes : https://github.com/twentyhq/core-team-issues/issues/951
2025-05-27 19:44:13 +02:00
5ce462b17e i18n - translations (#12330)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-27 18:12:10 +02:00
017940b2cb better logging in order to investigate later one on this kind of error (#12326)
# extracting domain emails

Added new test cases covering weird but valid email formats (plus
addressing, subdomains, international domains, etc.) to identify
potential failures in the current implementation.

Two tests with quoted local parts containing @ symbols or quotes are
marked as skipped since they're expected to fail with the current simple
string splitting approach. They are too exotic IMO, we should throw
errors.

## Next
We will monitor errors related to this and update accordingly later on.


### Note 
technically, quotes are possible in RFC see
[here](https://stackoverflow.com/questions/4816424/are-single-quotes-legal-in-the-name-part-of-an-email-address)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-27 18:10:48 +02:00
WeikoandGitHub f210d274bf Role page various fixes (#12324)
Various fixes from fast follows

- Sort roles by alphabetical order
- Change some tooltips
- During role creation, role should have all permissions enabled by
default
- Changed Permission icons design and refactored duplicating logic in a
dedicated component
- Changed "Revoked by" design
- Display role icon in default role picker
- Workspace member avatar was missing in role list and member picker
- Set "seeded" member role as editable for new workspaces
- Various css fixes
2025-05-27 17:58:55 +02:00
WeikoandGitHub 8051646567 Handle restricted objects #1 refactor permissions map + return object permissions from gql (#12313)
## Context
- Introduced objectPermissions in currentUserWorkspace which uses role
permissions from cache so we can fetch granular permissions from the API
- Refactored cached role permissions to map permissions with object
metadata id instead of object metadata name singular to be more flexible

New Cache
<img width="574" alt="Screenshot 2025-05-27 at 11 59 06"
src="https://github.com/user-attachments/assets/1a090134-1b8a-4681-a630-29f1472178bd"
/>

GQL
<img width="977" alt="Screenshot 2025-05-27 at 11 58 53"
src="https://github.com/user-attachments/assets/3b9a82b0-6019-4a25-a6e2-a9e0fb4bb8a0"
/>


Next steps: Use the updated API in the FE to fetch granular permissions
and update useHasObjectReadOnlyPermission hook
2025-05-27 17:42:26 +02:00
651ad38e79 feat: trim empty space (#12293)
Trim trailing spaces of the input, instead of manually trimming, thus
improving the user experience.
Fixes #12279

### Screencast
[Screencast from 2025-05-26
21-03-54.webm](https://github.com/user-attachments/assets/cc40be5a-d260-4a20-bbc8-c0b21ddbbd9b)

---------

Co-authored-by: Devessier <baptiste@devessier.fr>
2025-05-27 17:31:54 +02:00
MarieandGitHub 13d13144b7 [permissions] Override repository and manager methods #2 (#11929)
Closes https://github.com/twentyhq/core-team-issues/issues/747
2025-05-27 15:12:30 +00:00
MarieandGitHub 97cc1b3cbb [permissions V2] Throw when objectPermissions not found in datasource (#12325)
I encountered a bug where I was missing permissions while calling
searchResolver because the repository from
`twentyORMManager.getRepository` was missing permissions itself.
The repository was returned from the cached repositories map using a
repository key feature the roleId, the rolesVersion and
featureFlagMapVersion.
I was not able to reproduce but this error should not go unnoticed: we
always expect to find objectPermissions for every roleId in the
datasource now.
I was not able to understand what happened for now but I think throwing
the error will help keeping an eye on it
2025-05-27 15:01:11 +00:00
7cacccf0b8 UNAUTHORIZED gmail error (#12262)
# Gmail OAuth authentication flow issues

### TLDR
This error is not an error and therefore should be treated as a simple
redirect with a snackbar.

### More details
Fixing incomplete OAuth token exchange processes and improving error
handling for empty Gmail inboxes.
The changes include modifications to OAuth guards, to ensure that if a
user clicks "cancel" instead of completing the authentication workflow
if fails

## Before:
Redirection from `/settings/accounts` to `app.twenty.com` with an
`UNAUTHORIZED` error

## After :
<img width="948" alt="Screenshot 2025-05-26 at 18 04 37"
src="https://github.com/user-attachments/assets/62c8721e-c2b3-4e3d-ad0b-e4059dfb7a98"
/>


Fixes https://github.com/twentyhq/twenty/issues/11895

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-27 16:45:42 +02:00
Thomas TrompetteandGitHub 4b25aabfa2 Update schema and add tests (#12314)
For database event triggers, we remove the before / after logic. We go
directly with the properties
<img width="211" alt="Capture d’écran 2025-05-27 à 11 40 36"
src="https://github.com/user-attachments/assets/a05bd3c1-104b-477b-be52-d56846ce7e63"
/>

To achieve this without changing the shape of events, we need to handle
keys using dots, such:
```
'properties.after.name': {
    icon: 'IconBuildingSkyscraper',
    type: FieldMetadataType.TEXT,
    label: 'Name',
    value: 'My text',
    isLeaf: true,
},
```

This PR:
- adds logic to handle the case where the key has dot included
- adds tests
2025-05-27 15:57:28 +02:00
nitinandGitHub 78f8562457 fix: prevent drag selection from blocking input focus (#12322)
closes #12309
Fixes input elements becoming unusable due to drag selection preventing
default browser behavior.

**Problem:**
- Input elements couldn't receive focus because `event.preventDefault()`
was called unconditionally
- Removing `preventDefault()` broke click-outside-to-deselect
functionality

**Solution:**
- Only call `preventDefault()` when actually starting drag selection
- Preserves input focus while maintaining drag selection and deselection
behavior

**Changes:**
- Move `event.preventDefault()` inside the `shouldStartSelecting`
condition
- Update test to reflect correct behavior for disabled elements
2025-05-27 14:51:48 +02:00
Paul RastoinandGitHub feeb032602 Add mcp.json to gitignore (#12321)
# Introduction
In order to avoid pushing secrets within an project scoped mcp.json
configuration
[Related
docs](https://docs.cursor.com/context/model-context-protocol#configuration-locations)
2025-05-27 14:06:21 +02:00
EtienneandGitHub 0275fad5f7 billing - remove deprecated endpoint (#12315)
staging and main env config in stripe updated (prod already updated)
2025-05-27 14:03:37 +02:00
Raphaël BosiandGitHub d85c45a4cf Fix last row disappearing when dragging a row in the table (#12297)
# Fix last row disappearing when dragging a row in the table

Fixes https://github.com/twentyhq/core-team-issues/issues/836

The issue came from the fact that the provided placeholder was not
mounted at the right place (after the footer when it should be mounted
before it).

I created a context to which we can pass the placeholder. We can use
this placeholder anywhere inside the table by using
`RecordTableBodyDroppablePlaceholder`.

## Before


https://github.com/user-attachments/assets/39a2e45b-6d97-4450-bfee-12135a873a1d


## After


https://github.com/user-attachments/assets/ca126819-67f2-4358-b644-85172fef3b8f
2025-05-27 12:02:24 +02:00
c7b3ebc743 i18n - translations (#12312)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-27 11:46:00 +02:00
Paul RastoinandGitHub 42d493d31d Commit index.ts twenty-ui (#12310)
Related to https://github.com/twentyhq/twenty/pull/12282
2025-05-27 09:37:19 +00:00
Baptiste DevessierandGitHub 7b5d6a2ffc Open the executed workflow run in the side panel (#12284)
> [!WARNING]
> This PR introduces a new way to interact with workflow runs. It comes
with a few known flaws that will be solved in a second time.

## Launching a Test


https://github.com/user-attachments/assets/89b0eb63-d276-4ac5-a5d8-665d0084e0c5

## Triggering a workflow with a manual trigger


https://github.com/user-attachments/assets/047975d4-a24d-4cf0-b617-525965e3bfd8

Closes https://github.com/twentyhq/core-team-issues/issues/812
2025-05-27 11:34:02 +02:00
Antoine MoreauxandGitHub a83279ddce fix(dropdown): separator width + DropdownHeader height (#12285)
## Before

![CleanShot 2025-05-26 at 15 26
35@2x](https://github.com/user-attachments/assets/d6247af2-6008-4234-b777-13597c697b12)

## After

![CleanShot 2025-05-26 at 15 26
42@2x](https://github.com/user-attachments/assets/65447c84-4313-4f9a-831d-efc1eccd3d26)
2025-05-27 11:17:03 +02:00
8cf3b83bb9 fix/replace-set-primary-with-bookmark-12268 (#12276)
## 🛠️ What this PR fixes

Fixes #12268

This PR fixes the UI behavior where the "Set as Primary" button was
incorrectly shown for emails or phones that are already marked as
primary. Instead, users now see a bookmark icon indicating the entry as
primary.

## 🎥 Demo

The attached video demonstrates the updated UI where the "Set as
Primary" button is hidden for primary contacts or emails and replaced by
a bookmark icon.



https://github.com/user-attachments/assets/9afcc818-fbb4-4e7c-8fa2-093fdc7d8a26

---------

Co-authored-by: Davinder Kumar <davinder.kumar@intverse.io>
Co-authored-by: Devessier <baptiste@devessier.fr>
2025-05-27 11:10:12 +02:00
MarieandGitHub 92aa6a8e1a filter out 500 errors from sentry-captured errors in FE (#12307)
Since https://github.com/twentyhq/twenty/pull/12286 we are now capturing
in sentry graphql queries errors in the FE.
We want to exclude InternalServerErrors because they are already
captured in sentry from the BE.
2025-05-27 10:43:26 +02:00
Félix MalfaitandGitHub 9cdd0fdac0 Revert "Client config not render blocking (#12300)" (#12302)
This reverts commit 4ce7fc6987, to take
more time to address PR comments
2025-05-27 09:04:47 +02:00
Félix MalfaitandGitHub e8532faaaa Fix find duplicates typing (id -> uuid) (#12301)
Minor fix of a bug I saw while testing in staging
2025-05-27 08:02:47 +02:00
Félix MalfaitandGitHub 4ce7fc6987 Client config not render blocking (#12300)
Changes for performance improvement.
The primary improvements include replacing GraphQL queries with
REST-based client configuration fetching and making the client config
non render-blocking
2025-05-27 00:06:48 +02:00
martmullandGitHub aa58259019 11744 emails broken image in emails (#12265)
- refactor file tokens
- update file token management
  - generate one token per file per workspaceId
  - move token from query params to url path
2025-05-26 22:05:21 +02:00
MarieandGitHub 69badf2a66 Capture FE GraphQL exceptions in sentry (#12286)
We should capture graphQL exceptions thrown in the FE in Sentry.

All the more so as we have just cleaned back-end errors in sentry,
preventing 4xx errors from being wrongfully sent to sentry.
Those 4xx errors should, except for `Unauthenticated` and `Forbidden`
errors (for now - this list can evolve), trigger a sentry FE error, as
we are not suppose to let users of the product interface trigger queries
that will fail with 4xx errors (for instance a malformed input).

We still miss an efficient way to group those errors together in sentry.
It could be the message but the message may be different for each user
if it contains user-specific data, and we don't always have control on
the message.
This can be done later as we iterate on improving sentry
2025-05-26 17:23:19 +00:00
Raphaël BosiandGitHub a15451dab2 Fix close command menu button (#12282)
Fixes #12280 

The `dataClickOutsideId` and `dataGloballyPreventClickOutside` props
weren't passed to the button components.

This PR fixes this and introduces the type `ClickOutsideAttributes`.



https://github.com/user-attachments/assets/38b1a6f9-8f3a-43d2-aa7b-aaa259ac6737
2025-05-26 15:37:46 +02:00
Thomas TrompetteandGitHub ec4e4740d2 Make workflow statuses more resilient (#12263)
Workflow statuses are often broken. I did not figured out why yet. But I
see two causes that can be fixed:
- statuses calculation are really complicated today, just to spare a
call to the database
- job is not indempotent, it is using the combination of the previous
statuses + the update to calculate the new statuses. Which means that
once broken, next updates will be broken as well

Instead, we now:
- fetch workflow versions
- get the statuses from these.
It simplifies the code and make the job indempotent.
2025-05-26 13:05:18 +00:00
BOHEUSGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
742af7884a Update Makefile in local setup to clean postgres instead of pg-spile (#12273)
In Makefile used for Local dev setup spilo container is still in the use
despite deprecating it in 0.43.0

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-26 12:20:19 +02:00
524a1d78d2 Refactor drag selection: Replace external library with custom implementation and add auto-scroll (#12134)
Closes #12076
Closes #11764

Replaced the `@air/react-drag-to-select` library with a custom
implementation to get better control over the selection behavior and add
auto-scroll functionality.

**What changed:**
- Removed external drag selection dependency 
- Built custom drag selection from scratch using pointer events --
@charlesBochet
- Added auto-scroll when dragging near container edges
- Fixed boundary detection so selection stays within intended areas
- Added proper `data-select-disable` support for checkboxes and other
non-selectable elements

The new implementation gives us full control over the selection logic
and eliminates the external dependency while adding the auto-scroll
feature that was **not** requested 😂

**Auto Scroll**



https://github.com/user-attachments/assets/3509966d-5b6e-4f6c-a77a-f9a2bf26049f



related to #12076 


https://github.com/user-attachments/assets/2837f80e-728c-4739-a0e2-b8d7bc83a21a

**Also fixed:**
- Record board column height not extending to the bottom (styling issue
I found while working on this)

before:

<img width="1512" alt="Screenshot 2025-05-19 at 23 58 54"
src="https://github.com/user-attachments/assets/602b310f-7ef6-44f6-99e9-da5ff59b31d3"
/>

after:

<img width="1512" alt="Screenshot 2025-05-19 at 23 56 40"
src="https://github.com/user-attachments/assets/1d0ecb5c-49e0-4f03-be3b-154a6f16a7a4"
/>

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-26 11:58:22 +02:00
Baptiste DevessierandGitHub 621a779526 Prevent setting primary link as primary link (#12266)
## Before

It was possible to set the primary link as the... primary link.


https://github.com/user-attachments/assets/a6ffefab-50c5-403e-9aa1-5acc08593168

## After


https://github.com/user-attachments/assets/494e45c4-de15-4b52-b71b-032a2ca77c35

- We display the bookmark icon for the first link if there is more than
one link to show. (`index === 0 && links.length > 1`)
- It's never possible to "Set as Primary" the first link (`index > 0`)
- I introduced abstractions to make it easy to solve a similar issue for
phones and emails fields (see
https://github.com/twentyhq/twenty/issues/12268)
- Wrote stories to document the current improper behavior of phones and
emails fields
2025-05-23 18:55:26 +02:00
bd8eace0b1 i18n - translations (#12269)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-23 18:44:47 +02:00
Lucas BordeauandGitHub 371fdba1f8 Changed the auto matching of columns in import (#12181)
This PR changes the way we do automatching in the import feature.

It uses [Fuse.js](https://www.fusejs.io/) to do a fuzzy text search on
fields and sub-fields.

The labels of sub-fields are now derived from the common config constant
we have for sub-fields.
2025-05-23 18:33:18 +02:00
f7ccb5d207 i18n - translations (#12267)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-23 18:31:10 +02:00
Raphaël BosiandGitHub 1e5257f95b Fixes active row state after opening the file preview (#12264)
Fixes #12093
This bug was quite hard to fix because it was an issue with the
`AnimatePresence` component of the framer motion library.

After investigating the issue with @Devessier, here is what we
understood:

Since the modal component has an exit animation but wasn't wrapped
inside an `AnimatePresence` component, the animation seemed to never be
marked as complete when we closed the modal and the component did not
appear anymore but was still in the dom.

This caused an issue when closing the side panel because the state
cleanup function of the command menu is triggered when its closing
animation is complete. This cleanup function emits a right drawer close
event, which is listened by the record table row to update it's state.

The `onExitComplete` was never triggered because the exit animation of
the modal was never considered as complete, and since it's a children
animation of the command menu `AnimatePresence`, this animation was
never considered as complete either (see [PresenceChild
doc](https://github.com/motiondivision/motion/blob/main/packages/framer-motion/src/components/AnimatePresence/PresenceChild.tsx).

This caused the cleanup function to never be executed and the close
event to never be emitted, so the row stayed active.

Before:


https://github.com/user-attachments/assets/a165039b-6203-43d6-b992-dcfb4dfb8f2b


After:


https://github.com/user-attachments/assets/42eab2e8-62c9-4c25-85d6-78210d7ebe89
2025-05-23 16:26:30 +00:00
5428348d7f fix(email-verification): prevent double email validation (#12250)
Fix #12177 
Fix #12171

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-23 16:24:26 +00:00
Antoine MoreauxandGitHub 8de85eea61 fix(): remove originHeader decorator (#12245)
Fix
https://github.com/twentyhq/core-team-issues/issues/858#issuecomment-2891213392
Fix #11966 
Fix #12175
2025-05-23 18:01:36 +02:00
Antoine MoreauxandGitHub 54edcc0ea7 fix(auth): prevent unexpected form effect trigger (#12261)
Ensure the form effect is not erroneously triggered when the sign-in
step is not related to email or password. This resolves potential state
inconsistencies during the authentication flow.


Fix #12176
2025-05-23 17:50:03 +02:00
martmullandGitHub f9afa589f4 Fix wrong email logo url (#12256)
Fix wrong twenty logo url
It does not fix all the https://github.com/twentyhq/twenty/issues/11744
issue, but this is a small step. The other step is pretty big so I split
the ticket in 2 PRs
2025-05-23 17:28:49 +02:00
af5762c8ba Infinite scrolling in relation picker menu (#12051)
https://github.com/user-attachments/assets/4be785e0-ea8a-4c8e-840e-6fa0a663d7ba

Closes #11938

---------

Co-authored-by: martmull <martmull@hotmail.fr>
2025-05-23 17:23:09 +02:00
GuillimandGitHub 6ef9a3b4c9 Empty Gmail box bug (#12225)
if gmail is empty, there is an error. This PR handles this use-case
2025-05-23 17:21:31 +02:00
martmullandGitHub 88b967dfb8 Cast typeorm QueryFailedError to BadRequestException for the rest api (#12217) 2025-05-23 17:00:45 +02:00
MarieandGitHub 362d540aac Misc. of sentry improvements (#12233)
This PR mixes various initiatives to improve visibility on sentry 

**1. Catch errors on workflow jobs**
commit [catch workflowTriggerExceptions in job
handle](https://github.com/twentyhq/twenty/commit/1dbba8c9e27fed8fe01c5ac91d492720c45ba7a5)
@thomtrp 

**2. Fix type in messagingImportExceptionHandler** 
commit [fix type issue on
messagingImportExceptionHandler](https://github.com/twentyhq/twenty/commit/919bb3844c2e11f929a01dff0539e0a2ec7e4b00)
@guillim 

**3. Catch invalid uuid errors thrown by Postgres by rightfully typing
expected id as uuid**
commits [use UUIDFilter instead of IDFilter to get graphqlError in case
of malformed
id](https://github.com/twentyhq/twenty/commit/57cc315efeb0365b1cd589f7487dbfc886338d26),
[use UUIDFilter
(2)](https://github.com/twentyhq/twenty/commit/304553d770426362ee8bfcd3c2e1f0066abe2c04),
[fix ids typed as UUID instead of
ID](https://github.com/twentyhq/twenty/commit/f95d6319cf9290a5ae1d59eb634617a511411633)
@Weiko 
⚠️⚠️⚠️ when we deploy this PR we need to flush the schema types from
redis as this PR changes them ⚠️⚠️⚠️


**4. Do not group UNKNOWN errors together**
commit [do not group unknown errors
together](https://github.com/twentyhq/twenty/commit/c299b39c8fdcc4d6656dc5ce58437e4365cd60b0)
Some CustomException classes have introduced UNKNOWN error codes as a
default fallback error code. We use CustomException codes to group
issues together, but we don't want to do it with UNKNOWN error as they
may not have anything in common. For exemple [this sentry for UNKNOWN
code](https://twenty-v7.sentry.io/issues/6605750776/events/a72272d8941b4fa2add9b1f39c196d3f/?environment=prod&environment=prod-eu&project=4507072499810304&query=Unknown&referrer=next-event&stream_index=0)
groups together "Unknown error importing calendar events for calendar
channel...", "Insufficent permissions...", to name a few.

**5. Improve postgres error grouping**
commit [group together postgres
errors](https://github.com/twentyhq/twenty/commit/567c25495e37cdccfc9010f346145f7d5cc46a54)
Postgres error are thrown by typeORM as QueryFailedError. we have a lot
of them on sentry where they are badly grouped They are currently
grouped on sentry according to the stack trace, which leads them to
sometimes be grouped even if they don't have anything in common : for
exemple [this sentry for
QueryFailedError](https://twenty-v7.sentry.io/issues/6563624590/events/2d636821e27a448595b647b4b5a7d6a8/?environment=prod&environment=prod-eu&project=4507072499810304&query=is%3Aunresolved%20%21issue.type%3A%5Bperformance_consecutive_db_queries%2Cperformance_consecutive_http%2Cperformance_file_io_main_thread%2Cperformance_db_main_thread%2Cperformance_n_plus_one_db_queries%2Cperformance_n_plus_one_api_calls%2Cperformance_p95_endpoint_regression%2Cperformance_slow_db_query%2Cperformance_render_blocking_asset_span%2Cperformance_uncompressed_assets%2Cperformance_http_overhead%2Cperformance_large_http_payload%5D%20timesSeen%3A%3E10&referrer=previous-event&sort=date&stream_index=0)
groups together "user mapping not found for "postgres" and "invalide
type for uuid: 'fallback-id'" to name a few. I attempted to improve the
grouping by grouping them with a new custom fingerPrint composed of the
[code returned by
Postgres](https://www.postgresql.org/docs/current/errcodes-appendix.html)
+ the truncated operation name (Find, Aggregate, Check...). This is
still not ideal as postgres code are quite broad - we could have the
same error code for two Find operations with different causes. let's
give this a try !
2025-05-23 13:36:02 +00:00
Raphaël BosiandGitHub 5da446d7f7 Display "Untitled" in MultipleRecordPicker (#12246)
Fixes #11940 

Display untitled with the object name for untitled records in
`MultipleRecordPicker`:

![CleanShot 2025-05-23 at 11 29
20@2x](https://github.com/user-attachments/assets/062df33c-5c7a-4170-a973-8a1fc1b04729)
2025-05-23 14:51:16 +02:00
Lucas BordeauandGitHub c98439d76a Fixed RecordShowEffect request bug (#12247)
This PR fixes the RecordShowEffect that was overwriting the record store
with an empty state during the request loading time.
2025-05-23 11:45:05 +00:00
EtienneandGitHub 3d21e1ce26 remove activity fallback record in RelationFromManyFieldDisplay (#12232)
EDITED ⬇️ 

Context
When fixing relation fields preview in this
[PR](https://github.com/twentyhq/twenty/pull/11745/files#diff-10073c6310707810d002bceef587936ed5d31dba2ea5babbb4d452a7f1e756b5R31-R35),
I've (try to) fixed NoteTarget (and TaskTarget) field preview adding
[fallback
record](https://github.com/twentyhq/twenty/pull/11745/files#diff-da3ccb70824f1792351457dbee66dd75e48e45ff8e6e0f768f402e35256377bcR54-R61).

It introduces the sentry error (findOneNote/Task with 'fallback-id') :
when activity is soft deleted, associated activityTarget is not. In
TableView, when displaying Note/Task field in view for a record with a
soft deleted ntoe/task, 'fallback-id' record chip is clickable.

Solution - seen with Charles - Remove fallback-id record + Hide
NoteTarget and TaskTarget field preview - awaiting ManyToMany relation
are updated in few weeks

<img width="1160" alt="Screenshot 2025-05-23 at 11 07 06"
src="https://github.com/user-attachments/assets/73b1629a-67a0-43cc-ac2c-ddeea524ed6e"
/>


Test - RelationFromManyFieldDisplay in Table view & Settings field
preview

closes https://github.com/twentyhq/twenty/issues/12218
2025-05-23 12:25:12 +02:00
EtienneandGitHub ddab513c0b patch messages in thread (#12191)
closes https://github.com/twentyhq/twenty/issues/12190
2025-05-23 10:24:13 +00:00
Baptiste DevessierandGitHub ec9d8e4e95 Discard empty and null links in Links fields (#12188)
This PR has several objectives:

- Ignore invalid and empty links in the frontend
- Ignore empty links when creating or updating a link field in the
backend
- Throw an error when trying to create or update a link field with an
invalid link

The logic is mostly the same in the frontend and the backend: we take
the initial primaryLink and the secondaryLinks, we discard all the empty
links (with `url === '' || url === null`), and the primaryLink becomes
the first remaining link.

## Frontend

There are three parts in the frontend where we have to remove the empty
links:

- LinksDisplay
- LinksFieldInput
- isFieldValueEmpty; used in RecordInlineCell

## Backend

I put the logic in
`packages/twenty-server/src/engine/core-modules/record-transformer/services/record-input-transformer.service.ts`
as it's used by the REST API, the GraphQL API, and by Create Record and
Update Record actions in the workflows.
2025-05-23 11:13:10 +02:00
Lucas BordeauandGitHub 75e4a5d19b Fixed dropdown flip and resize edge cases (#12234)
This PR fixes the dropdown resize problems we had with some edge cases,
the most common was that when opening a dropdown that is placed near the
bottom end of the screen the dropdown would shrink to a ridiculously
small height instead of flipping.

With this PR we implement a mechanism that respects all of the existing
behaviors while fixing this edge case, and most of all allows for the
incoming refactor on harmonization of dropdown content width.

Before : 



https://github.com/user-attachments/assets/6da3b291-e60c-4353-94fb-45fef55ee0e1

After : 



https://github.com/user-attachments/assets/c9fd9a34-f5de-4701-a301-08cba1eafdad

Fixes https://github.com/twentyhq/core-team-issues/issues/980
2025-05-23 11:07:47 +02:00
Antoine MoreauxandGitHub 710c859f4e feat(settings): replace TextInputV2 with TextInput and update hotkey … (#12236)
…scope

Replaced TextInputV2 with TextInput in
SettingsSecurityApprovedAccessDomain for consistency with the input
component. Added a new hotkey scope for the REST Playground page in
PageChangeEffect to enable keyboard shortcut menu functionality.

Fix #10981
2025-05-23 11:03:31 +02:00
ac98ecf3fc Fix/exit settings link stuck 12235 (#12243)
## 🛠️ What this PR fixes
Fixes #12235

The "Exit Settings" link was stuck after navigating using a keyboard
shortcut(s).
This PR ensures the Exit Settings button works correctly.

## 🎥 Demo
The attached video demonstrates the issue being fixed and the link
behaving correctly.
**Note:** You can view the shortcuts I pressed in the bottom-left corner
of the video. To ensure they are clearly visible, avoid letting the
video’s progress bar overlap them by moving the cursor away from the
video after starting playback.


https://github.com/user-attachments/assets/4d705ddd-7b48-45c1-a292-127b9a88b68d

---------

Co-authored-by: Davinder Kumar <davinder.kumar@intverse.io>
2025-05-23 10:32:56 +02:00
Thomas TrompetteandGitHub cced069d28 Fix discard workflow draft (#12230)
Fixes https://github.com/twentyhq/core-team-issues/issues/997

Fetch workflow id in workflow version is not done by default since the
refacto of relations. So we delete the version from cache once discarded
by we cannot clean the workflow using the workflow id in the version.

This PR adds the workflow id to the query.

Before


https://github.com/user-attachments/assets/03663bba-6c9e-4357-9326-0fb33c707fe6

After


https://github.com/user-attachments/assets/e6bb910b-2d9f-412f-a349-cd4b076aca65
2025-05-23 10:17:18 +02:00
Raphaël BosiandGitHub 051f0fc83f Use data attributes for click outside instead of classNames (#12228)
We previously used classnames to exclude elements from the click outside
listener.

With this PR we can now use `data-click-outside-id` instead of
`classNames` to target the elements we want to exclude from the click
outside listener.

We can also add `data-globally-prevent-click-outside` to a component to
globally prevent triggering click outside listeners for other
components. This attribute is especially useful for confirmation modals
and snackbar items.

Fixes #11785:


https://github.com/user-attachments/assets/318baa7e-0f82-4e3a-a447-bf981328462d
2025-05-22 18:10:51 +02:00
Paul RastoinandGitHub 45c89a46d6 FieldMetadata ENUM CREATE UPDATE server validation and integration tests (#12121)
# Introduction

Big diff a lot of tests and snapshots ( real diff < 500+ )

close https://github.com/twentyhq/twenty/issues/12117
close https://github.com/twentyhq/twenty/issues/12133

## What has been done here
Implemented a strong integration coverage on both fieldmetadata`SELECT`
`UPDATE` and `CREATE`.
Implemented server side validation for the options `value` `label` `id`
and collision issue with also `position`

We could improve:
- Position validation
- DefaultValue validation

## Update
```ts
 PASS  test/integration/metadata/suites/field-metadata/update-one-field-metadata-select.integration-spec.ts (41.054 s)
  Field metadata select update tests group
    ✓ Update should succeed with provided option id (2565 ms)
    ✓ Update should succeed with valid default value (1469 ms)
    ✓ Update should succeed with various options id (1257 ms)
    ✓ Update should succeed without option id (1286 ms)
    ✓ Update should trim option values (1366 ms)
    ✓ Update should succeed with default value and no options (1122 ms)
    ✓ Update should fail with unknown default value and no options (1075 ms)
    ✓ Update should fail with only white spaces id (1195 ms)
    ✓ Update should fail with empty string id (1058 ms)
    ✓ Update should fail with null id (1066 ms)
    ✓ Update should fail with not a string id (1098 ms)
    ✓ Update should fail with too long id (1373 ms)
    ✓ Update should fail with only white spaces label (1034 ms)
    ✓ Update should fail with empty string label (1057 ms)
    ✓ Update should fail with null label (1100 ms)
    ✓ Update should fail with not a string label (1144 ms)
    ✓ Update should fail with too long label (1273 ms)
    ✓ Update should fail with only white spaces value (1385 ms)
    ✓ Update should fail with empty string value (1035 ms)
    ✓ Update should fail with null value (1068 ms)
    ✓ Update should fail with not a string value (1021 ms)
    ✓ Update should fail with too long value (1134 ms)
    ✓ Update should fail with invalid option id (1137 ms)
    ✓ Update should fail with empty options (1238 ms)
    ✓ Update should fail with invalid option value format (1104 ms)
    ✓ Update should fail with comma in option label (1004 ms)
    ✓ Update should fail with duplicated option values (1015 ms)
    ✓ Update should fail with duplicated option ids (1079 ms)
    ✓ Update should fail with duplicated option positions (1266 ms)
    ✓ Update should fail with duplicated trimmed option values (1220 ms)
    ✓ Update should fail with undefined option label (1029 ms)
    ✓ Update should fail with an invalid default value (1142 ms)
    ✓ Update should fail with an unknown default value (1081 ms)
    ✓ Update should fail with undefined option value (1086 ms)

Test Suites: 1 passed, 1 total
Tests:       34 passed, 34 total
Snapshots:   28 passed, 28 total
Time:        41.079 s
```


## Create
```ts
 PASS  test/integration/metadata/suites/field-metadata/create-one-field-metadata-select.integration-spec.ts (38.292 s)
  Field metadata select creation tests group
    ✓ Create should succeed with provided option id (2096 ms)
    ✓ Create should succeed with valid default value (1316 ms)
    ✓ Create should succeed with various options id (1113 ms)
    ✓ Create should succeed without option id (1378 ms)
    ✓ Create should trim option values (1296 ms)
    ✓ Create should fail with only white spaces id (1000 ms)
    ✓ Create should fail with empty string id (1325 ms)
    ✓ Create should fail with null id (1060 ms)
    ✓ Create should fail with not a string id (1142 ms)
    ✓ Create should fail with too long id (1321 ms)
    ✓ Create should fail with only white spaces label (999 ms)
    ✓ Create should fail with empty string label (1163 ms)
    ✓ Create should fail with null label (1198 ms)
    ✓ Create should fail with not a string label (1678 ms)
    ✓ Create should fail with too long label (1527 ms)
    ✓ Create should fail with only white spaces value (1200 ms)
    ✓ Create should fail with empty string value (1102 ms)
    ✓ Create should fail with null value (1037 ms)
    ✓ Create should fail with not a string value (1462 ms)
    ✓ Create should fail with too long value (896 ms)
    ✓ Create should fail with invalid option id (997 ms)
    ✓ Create should fail with empty options (1058 ms)
    ✓ Create should fail with invalid option value format (1190 ms)
    ✓ Create should fail with comma in option label (1142 ms)
    ✓ Create should fail with duplicated option values (872 ms)
    ✓ Create should fail with duplicated option ids (860 ms)
    ✓ Create should fail with duplicated option positions (1002 ms)
    ✓ Create should fail with duplicated trimmed option values (1336 ms)
    ✓ Create should fail with undefined option label (754 ms)
    ✓ Create should fail with an invalid default value (696 ms)
    ✓ Create should fail with an unknown default value (678 ms)
    ✓ Create should fail with undefined option value (699 ms)
    ✓ Create should fail with null options (720 ms)
    ✓ Create should fail with undefined options (686 ms)

Test Suites: 1 passed, 1 total
Tests:       34 passed, 34 total
Snapshots:   29 passed, 29 total
Time:        38.314 s
```

## Conclusion
As always any suggestions are welcomed ! Please let me know


## Discussion about validation governance
### Front
Front side will be dealing with zod validations schema that he will
handle and maintain by himself

### Back validation instances
- Validation hold through DTO declarations ( run by yoga through the
resolvers )
- Server programmatic validation and exceptions handling ( run through
the services )

For this refactor/fix we decided to stick to the current implementation
only touching the `Server programmatic validation and exceptions
handling` we will handle validation centralization when we will onboard
the `nestjs-query` deprecation/integration refactor.

### Vision
In the best of the world we could think of an intermediary model that
will handle and take responsibility of the validation decorators that
would be run programmatically through the service, Yoga would still
consume it ? then we would need to have enough grain in the service to
know the input has already validated

## Notes
Introduced zod back side in order to handle very atomic and primitive
validation
2025-05-22 17:58:59 +02:00
EtienneandGitHub 7cc0a7ae72 add checkFileExists method in file storage service (#12229) 2025-05-22 15:09:21 +00:00
WeikoandGitHub 08e32017fb Fix + column header in tables (#12221)
Fixes https://github.com/twentyhq/twenty/issues/12213



https://github.com/user-attachments/assets/1eb675f0-c8ba-4601-bcf7-c80c27a03d40
2025-05-22 16:32:07 +02:00
EtienneandGitHub aeee04415d add more logs to cleaning command (#12219) 2025-05-22 13:25:19 +00:00
Félix MalfaitandGitHub 79b4b3f783 Improve lazy loading (#12186)
WIP, using preview app to test performance (which was very bad)
2025-05-22 15:07:01 +02:00
Thomas TrompetteandGitHub 4ac47c2a1b Improve logs in workflow trigger (#12215)
- distinguish logs coming from webhook and job triggers
- add workspace and workflow ids to help debugging

Hard to debug sentry issue:

https://twenty-v7.sentry.io/issues/6605607134/?project=4507072499810304&query=&referrer=issue-stream&stream_index=7
2025-05-22 14:56:30 +02:00
0f9cdd9d39 i18n - translations (#12214)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-22 14:22:54 +02:00
MarieandGitHub b5544b6853 Fix timezone display + translate dates (#12147)
Fixes https://github.com/twentyhq/twenty/issues/11566 + translates dates

- Date display bug: We had an issue with date (not date time) display
depending on the timezone the user had selected. The date is stored in
the db as yyyy-mm-dd, eg. 2025-05-01 for **May 1st, 2025**. When
returned this date is formatted in a UTC DateTime at midnight, so
2025-05-1 00:00:00. Then when displaying the date we were converting
this date using the timeZone, so 2025-04-30 17:00:00, thus displaying
**April 30th, 2025**. The fix chosen is that we should not take into
account the timezone for date (not date time!) displays as we always
want to show the same date.
- Date translation: dates were not translated, not in their default
display (_May 1st, 2025_) nor in their relative display (_about a month
ago_). The lib we use for date formatting, date-fns, offers a
translation option with pre-built `Locale`s from their lib.
Unfortunately and surprisingly we cannot just use directly string locale
codes (like `fr-FR`), cf [open issue on
date-fns](https://github.com/date-fns/date-fns/issues/3660). A util was
introduced to offset this by dynamically importing the right date-fns
Locale based on the locale code.
2025-05-22 12:04:44 +00:00
EtienneandGitHub 0ac4cc6899 captcha - keep consistency with token send to validation (#12195)
[Sentry
error](https://twenty-v7.sentry.io/issues/6494360796/events/322590f8af5c4475beebb66e5f22a2f7/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=previous-event&seerDrawer=true&sort=date&stream_index=6)
raised because of invalid argument type (undefined in some case when
string is expected)

closes https://github.com/twentyhq/core-team-issues/issues/869 and
closes https://github.com/twentyhq/twenty/issues/12208
2025-05-22 13:49:23 +02:00
Thomas TrompetteandGitHub 4e7a7ce893 Remove calendar cursor (#12200)
Fixes https://github.com/twentyhq/twenty/issues/12125

The root cause of the infinite loop was the calendar cursor. In some
cases, it was not properly displayed and was causing the loop because of
its animation that was always restarting.

We agreed with @FelixMalfait and @Bonapara that given the current
importance of the feature and the amount of issues associated, we remove
the cursor for now.
2025-05-22 13:35:30 +02:00
Charles BochetandGitHub 9753637693 Fix upgrade command (#12210) 2025-05-22 12:22:21 +02:00
ffdedf7af3 Fix "PageChangeEffect does not run when changing view on the same object" (#12196)
Fixes https://github.com/twentyhq/core-team-issues/issues/950

This issue was due to the memoization inside `useIsMatchingLocation`,
which was rerendered only if the pathname changed but not the search
params.

After discussion with @lucasbordeau, we decided to remove the hook
`useIsMatchingLocation` and to create an equivalent util function which
takes the location as an argument.

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-05-22 12:06:07 +02:00
Jordan ChalupkaandGitHub 6466f3fb45 add cursor rule for nx (#12199)
Adding a cursor rule for nx

## Changes
- Added `.cursor/rules/nx-rules.mdc`
- The rule provides structured guidelines for AI assistants to better
help developers
2025-05-22 12:05:52 +02:00
Abdul RahmanandGitHub c6627f1e99 fix: prevent empty state from scrolling in table view (#12197)
https://github.com/user-attachments/assets/334ffd15-a639-4947-8142-c19bc231c9bd



Closes #12132
2025-05-22 11:59:32 +02:00
Charles BochetandGitHub 1365c202d9 Increase auto subdomain generation cardinality (#12206)
Fixes https://github.com/twentyhq/twenty/issues/12204
2025-05-22 11:55:20 +02:00
Charles BochetandGitHub 891758bb89 Fix docker setup (#12209)
For fresh install, we need the migrations to happen before the upgrade
command is triggered as the upgrade command is a NestJS command and the
app will try to load env variables from db
2025-05-22 11:32:00 +02:00
Raphaël BosiandGitHub 342583e891 Fix stacking multiple time the same record in the side panel (#12192)
Fixes #12043 

This bug had two distinct root causes:
- The command menu closing wasn't triggering correctly because of a
hotkey scope issue. We reset the hotkey scope to record index inside
`useLeaveTableFocus` but we should do it only when needed
- The portal on top of the table cell didn't stop the propagation of the
click so the table cell was opened twice (once in the portal and once in
the underlying cell)

Before:


https://github.com/user-attachments/assets/16c41135-fff9-4f89-a512-6a7c0e143190


After:


https://github.com/user-attachments/assets/865b6063-5f82-4f44-b0c8-d03f5955d685
2025-05-22 11:13:20 +02:00
Paul RastoinandGitHub 1404513ec5 docs(website): upgrade guide 0.54 (#12194) 2025-05-21 23:57:37 +02:00
EtienneandGitHub 786ad088b3 clean not found file - add logs (#12198) 2025-05-21 23:56:02 +02:00
Paul RastoinandGitHub 8d105417ba Add forgotten 054 commands (#12193)
Wrongly named branch
2025-05-21 17:59:17 +02:00
Charles Bochet d38f448d05 Move fieldMetadata migration from metadata to core 2025-05-21 16:36:04 +02:00
Charles Bochet dc2d7f7c94 Fix upgrade command for 0.54 2025-05-21 16:25:39 +02:00
6c9d17eee7 i18n - translations (#12189)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-21 16:20:48 +02:00
martmullandGitHub 578f07374b 922 remove todos from 11809 after release (#12183)
- remove todos
- remove workflow-event-listener.workspace-entity.ts
2025-05-21 16:15:48 +02:00
Paul RastoinandGitHub 85a17a54b3 Do not upgrade if no migrate (#12187) 2025-05-21 16:01:03 +02:00
martmullandGitHub a5b212369b Set findOneServerlessFunction result nullable (#12179)
solves https://github.com/twentyhq/twenty/issues/11819
remove fetch query when deleting code step
2025-05-21 13:59:20 +00:00
MarieandGitHub 8c6569be3b Add relation exceptions (#12185)
Introducing a class of RelationException extending CustomException to
help grouping those exception in sentries by ExceptionCode.
I did not introduce a filter as these are thrown in utils that can be
used in multiple places now or in the future, and filters are to be
added at resolver-level.
2025-05-21 15:53:25 +02:00
Raphaël BosiandGitHub c982bcdb52 Introduce focus stack to handle hotkeys (#12166)
# Introduce focus stack to handle hotkeys

This PR introduces a focus stack to track the order in which the
elements are focused:
- Each focused element has a unique focus id
- When an element is focused, it is pushed on top of the stack
- When an element loses focus, we remove it from the stack 

This focus stack is then used to determine which hotkeys are available.
The previous implementation lead to many regressions because of race
conditions, of wrong order of open and close operations and by
overwriting previous states. This implementation should be way more
robust than the previous one.

The new api can be incrementally implemented since it preserves
backwards compatibility by writing to the old hotkey scopes states.
For now, it has been implemented on the modal components.

To test this PR, verify that the shortcuts still work correctly,
especially for the modal components.
2025-05-21 15:52:40 +02:00
7f1d6f5c7f Continue migration schema from metadata to core (#12168)
2nd part of the migration - this time we're migrating all the tables

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-05-21 15:44:13 +02:00
Félix MalfaitandGitHub 8c20bada79 Fix Scalar preload (#12184)
Chrome doesn't really respect preloading and was loading it before other
important assets, slowing down the app while in 99% of sessions people
don't check the REST API playground
2025-05-21 15:27:46 +02:00
Thomas TrompetteandGitHub 5c16b2752d Fix workflow sub objects updates validation (#12169)
Fixes https://github.com/twentyhq/core-team-issues/issues/983

- Enabling workflow version name update, even if not in draft status
- Assert draft when updating steps
- Enabling workflow run name update
2025-05-21 13:11:32 +00:00
MarieandGitHub 23ebd69541 Add Approved access domain exception filter (#12180)
We have approvedAccessDomain custom exceptions, but they were never
filtered while some of them reflects 4xx errors which we don't want to
be captured as 5xx errors
2025-05-21 14:36:14 +02:00
Baptiste DevessierandGitHub 4f4d216a21 Use null as the default value for link fields when persisting (#12173)
Follow up for https://github.com/twentyhq/twenty/pull/12113

I created stories for the LinksFieldInput component.
2025-05-21 14:11:38 +02:00
MarieandGitHub fdde7651a4 Fix email verification exception are not caught (#12174)
cf
[sentry](https://twenty-v7.sentry.io/issues/6606375182/?project=4507072499810304&query=is%3Aunresolved%20%21issue.type%3A%5Bperformance_consecutive_db_queries%2Cperformance_consecutive_http%2Cperformance_file_io_main_thread%2Cperformance_db_main_thread%2Cperformance_n_plus_one_db_queries%2Cperformance_n_plus_one_api_calls%2Cperformance_p95_endpoint_regression%2Cperformance_slow_db_query%2Cperformance_render_blocking_asset_span%2Cperformance_uncompressed_assets%2Cperformance_http_overhead%2Cperformance_large_http_payload%5D&referrer=issue-stream&sort=date&stream_index=4)

Email verification exception were not caught when thrown outside of
email-verification resolver, which be the case at authentication step.
2025-05-21 14:09:11 +02:00
EtienneandGitHub 76a8a644a2 fix mail thread design (#12167)
## Before
METADATA
<img width="400" alt="Screenshot 2025-05-21 at 11 34 51"
src="https://github.com/user-attachments/assets/b057dd3f-3ba1-4597-86a4-84157941f10a"
/>
SUBJECT
<img width="400" alt="Screenshot 2025-05-21 at 11 34 38"
src="https://github.com/user-attachments/assets/c41bc102-a84d-443f-bf8c-a77ca9eacd2c"
/>
SHARE_EVERYTHING
<img width="400" alt="Screenshot 2025-05-21 at 11 34 04"
src="https://github.com/user-attachments/assets/0ed39c88-3516-4ebf-9950-5ceabbc38f13"
/>


## After
SHARE_EVERYTHING
<img width="400" alt="Screenshot 2025-05-21 at 11 29 18"
src="https://github.com/user-attachments/assets/72efbf0f-021b-4012-8516-8b7b8318a1e8"
/>
METADAT
<img width="400" alt="Screenshot 2025-05-21 at 11 28 49"
src="https://github.com/user-attachments/assets/73065e89-c5ab-4938-ae71-e557aa3fe8f3"
/>
SUBJECT
<img width="400" alt="Screenshot 2025-05-21 at 11 28 35"
src="https://github.com/user-attachments/assets/10487afb-602d-41fc-bb66-15d71e2fb90f"
/>

Design :
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=23338-52430&t=9NbeB5idQaaOWPAq-0
2025-05-21 12:07:17 +02:00
EtienneandGitHub 3702fefc89 Move defaultAvatarUrl on userWorkspace + migration command (#12100)
closes https://github.com/twentyhq/core-team-issues/issues/883
2025-05-21 12:07:02 +02:00
martmullandGitHub 8e2d0139ed Emit proper event on createOrUpdate csv import operation (#12163)
- use proper event emitter when upserting records with csv import
- After:


https://github.com/user-attachments/assets/8303da38-2e35-4f4c-bb13-8a7a222971b7
2025-05-21 11:59:50 +02:00
819b3c6c0d followup #12033 (#12150)
follow up #12033

in #12033, SettingsDataModelFieldRelationForm I changed the the use of
objectMetadataItems to activeObjectMetadataItems, which filtered out
system objects. The naming was one factor for this confusion
Renaming it everywhere to specify that they don't include system objects

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-21 11:45:33 +02:00
Baptiste DevessierandGitHub c29ed1c0c9 Consider null values as empty values for link fields (#12113)
This pull request introduces changes to improve handling of nullable
values in link-related data structures and simplifies field value
generation logic. Key updates include adjustments to type definitions,
utility functions, and component logic to support `null` values for
links, along with the removal of the `generateDefaultFieldValue`
function in favor of `generateEmptyFieldValue`.

There will be a few more follow-up Pull Requests.

---

Closes https://github.com/twentyhq/twenty/issues/11844
2025-05-21 11:30:15 +02:00
EtienneandGitHub 7461b7ac58 lowercase user and invitation emails (#12130)
### Solution

> After discussion with charles & weiko, we chose the long term
solution.
> 
> Fix FE to request checkUserExists resolver with lowercased emails
> Add a decorator on User (and AppToken for invitation), to lowercase
email at user (appToken) creation. ⚠️ It works for TypeOrm .save method
only (there is no user email update in codebase, but in future it
could..)
> Add email lowercasing logic in external auth controller
> Fix FE to request sendInvitations resolver with lowercased emails
> Add migration command to lowercase all existing user emails and
invitation emails

> For other BE resolvers, we let them permissive. For example, if you
made a request on CheckUserExists resolver with uppercased email, you
will not found any user. We will not transform input before checking for
existence.

[link to comment
](https://github.com/twentyhq/twenty/pull/12130#discussion_r2098062093)

### Test 🚧 
- sign-in and up from main subdomain and workspace sub domain > Google
Auth (lowercased email) ✔️ | Microsoft Auth (uppercased email ✔️ &
lowercased email) | LoginPassword (uppercased email ✔️& lowercased
email✔️)
- invite flow with uppercased and lowercased ✔️
- migration command + sign-in ( former uppercased microsoft email ✔️) /
sign-up ( former uppercased invited email ✔️)

closes https://github.com/twentyhq/private-issues/issues/278, closes
https://github.com/twentyhq/private-issues/issues/275, closes
https://github.com/twentyhq/private-issues/issues/279
2025-05-21 11:06:29 +02:00
GuillimandGitHub 6ff5a5bafa fixing a microsoft graph api error (#12154)
The issue is "Microsoft Graph API unknown error: TypeError: Cannot read
properties of undefined (reading 'emailAddress')"

Sentry :
https://twenty-v7.sentry.io/issues/6605750776/events/7feb4f5949a64ab78bb429cffb7f0fea/?project=4507072499810304

Fixes https://github.com/twentyhq/core-team-issues/issues/981
2025-05-21 11:04:43 +02:00
GuillimandGitHub 91e487dd63 Catching "no licence" microsoft account (#12143)
Catching "no licence - removed" microsoft message channels. 

Current behabiour 
> ` MessageImportException [Error]: The mailbox is either inactive,
soft-deleted, or is hosted on-premise.`

Goal:
better track errors VS user mistakes

Context: 
A similar logic was already implemented for the calendar channels. I
just replicated it to message channels
2025-05-21 11:04:11 +02:00
Thomas TrompetteandGitHub fe25557337 Fix send email connected account (#12149)
Fixes https://github.com/twentyhq/twenty/issues/12144

Account owner id is not fetched anymore by default in find many
connected accounts.
This is coming from the relation migration, since account owner id is
not a basic field anymore.

Enforcing the fetch of account owner id + adding tests

<img width="251" alt="Capture d’écran 2025-05-20 à 18 23 44"
src="https://github.com/user-attachments/assets/3e3105a0-d3e8-4b5d-87b0-80d3e97ab034"
/>
2025-05-21 09:02:04 +00:00
ca78fc3f27 i18n - translations (#12148)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-20 17:21:01 +02:00
Thomas TrompetteandGitHub 538f831fc1 Prevent webhook trigger from enabling keys with spaces (#12146)
Fixes https://github.com/twentyhq/core-team-issues/issues/984

Variables do not support spaces. Preventing those in webhook triggers

<img width="501" alt="Capture d’écran 2025-05-20 à 16 22 19"
src="https://github.com/user-attachments/assets/563e4068-583f-4802-9309-a12c00143509"
/>
2025-05-20 17:04:48 +02:00
Lucas BordeauandGitHub 5f333ccd65 Fixes RelationFromManyFieldDisplay story (#12141)
This PR adds back and fixes the story for RelationFromManyFieldDisplay,
which was broken due to the removal of use-context-selector state.

The story was also setting unnecessary states, we now only keep one
state set in the recoil state.
2025-05-20 15:30:43 +02:00
GuillimandGitHub ad136b5246 better logging errors in messages (#12136) 2025-05-20 13:37:24 +02:00
Lucas BordeauandGitHub 0553f58c52 Removed use-context-selector completely (#12139)
This PR removes use-context-selector completely, so that any bug
associated with state synchronization between recoil and
use-context-selector disappears.

There might be a slight performance decrease on the table, but since we
have already improved the average performance per line by a lot, and
that the performance bottleneck right now is the fetch more logic and
the windowing solution we use, it is not relevant.

Also the DX has become so hindered by this parallel state logic recently
(think [cache
invalidation](https://martinfowler.com/bliki/TwoHardThings.html)), that
the main benefit we gain from this removal is the DX improvement.

Fixes https://github.com/twentyhq/twenty/issues/12123
Fixes https://github.com/twentyhq/twenty/issues/12109
2025-05-20 13:35:28 +02:00
9ba24b3654 Fix: Editing a task assignee relation from the list opens both the command menu and the multi item picker (#12138)
Fixes https://github.com/twentyhq/twenty/issues/12129

To fix this, we need to stop the click event from propagating up from
the ActivityTargetsInlineCell

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-05-20 12:14:19 +02:00
WeikoandGitHub 203d4fc84f Fix: Deleting an opportunity from the relation detail section deletes a person (#12137)
Fixes https://github.com/twentyhq/twenty/issues/12131

All instances of RecordDetailRelationRecordsListItem are sharing the
same DELETE_RELATION_MODAL_ID, this PR makes the modal ID unique for
each item.
2025-05-20 11:38:16 +02:00
Charles Bochet d6215cad46 Fix Modal stories 2025-05-20 00:53:32 +02:00
b48c8a11e0 Fix #10941: Make sure content adjusts itself when resizing cell (#11392)
Regarding issue #10941:
Previously, when resizing a column relative to the record's name, the
content did not properly adjust to the selected width. This issue
occurred because the parent element (the link) was not a flex container,
preventing the child elements from resizing accordingly.
This fix makes the Chip link inline-flex to allow proper content
adjustment.
Additionally, the Chip itself is now set to width: 100% so that it fully
adapts to its parent.
A small margin of 2 * theme.spacing(1) has also been added to improve
spacing.

Files changed:
packages/twenty-ui/src/components/chip/Chip.tsx
packages/twenty-ui/src/components/chip/LinkChip.tsx

**Video:**

https://github.com/user-attachments/assets/83832c25-0b70-490f-90ed-0d391addf6f8

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-20 00:43:26 +02:00
2477cad989 i18n - translations (#12135)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-20 00:14:45 +02:00
6f62636763 Refactor: Improve Docker volume permission handling and remove run-once service (#11405)
**Problem:**

The previous `docker-compose.yml` included a `change-vol-ownership`
service. This service was designed to run once upon startup to `chown`
the `server-local-data` and `docker-data` volumes to user/group
`1000:1000`. This was necessary because:
1. The main `server` and `worker` containers run as the non-root user
`1000` for security.
2. Docker typically creates/mounts named volumes initially owned by
`root`.
3. The application needs write access to these volumes.

However, this run-once service pattern causes problems in certain
deployment environments (like Coolify) that don't gracefully handle
services designed to exit after completing their task. This can lead to
deployment failures or warnings.

**Solution:**

This PR refactors the Docker setup to address the volume permission
issue directly within the Docker image build process, eliminating the
need for the run-once service.

**Changes:**

1.  **`packages/twenty-docker/docker-compose.yml`:**
    *   Removed the `change-vol-ownership` service definition entirely.
* Removed the `depends_on: change-vol-ownership` condition from the
`server` service definition.
* **Proposed Change:** Removed the `${STORAGE_LOCAL_PATH}` environment
variable from the `server-local-data` volume mounts for both `server`
and `worker` services. The path is now hardcoded to
`/app/packages/twenty-server/.local-storage`. (See Reasoning below).

2.  **`packages/twenty-docker/twenty/Dockerfile`:**
* In the final stage, *before* the `USER 1000` command, added lines to:
* Create the necessary directories: `RUN mkdir -p
/app/packages/twenty-server/.local-storage /app/docker-data` (and also
`/app/.local-storage` for safety, though it's likely unused by volumes).
* Set the correct ownership: `RUN chown -R 1000:1000 /app/.local-storage
/app/packages/twenty-server/.local-storage /app/docker-data`.

3.  **`packages/twenty-docker/twenty/entrypoint.sh`:**
* Added a check near the beginning of the script for the presence of the
now-potentially-unused `STORAGE_LOCAL_PATH` environment variable.
* If the variable is set, a warning message is printed to standard
output, informing the user that the variable might be deprecated and
ignored if the hardcoded path change in `docker-compose.yml` is
accepted.

**Reasoning:**

By creating the target directories
(`/app/packages/twenty-server/.local-storage` and `/app/docker-data`)
within the Docker image *and* setting their ownership to `1000:1000`
during the build (while still running as root), we leverage Docker's
volume initialization behavior. When a named volume is mounted to a
non-empty directory in the container image, Docker copies the content
and ownership from the image directory into the volume. This ensures
that when the `server` and `worker` containers start (running as user
`1000`), the volumes they mount already have the correct permissions,
eliminating the need for the separate `change-vol-ownership` service.

**Regarding `STORAGE_LOCAL_PATH`:**
The `docker-compose.yml` previously allowed configuring the path for
local storage via the `STORAGE_LOCAL_PATH` variable, defaulting to
`.local-storage`. Since the Dockerfile now explicitly creates and sets
permissions for `/app/packages/twenty-server/.local-storage`,
maintaining this configuration might be unnecessary or could potentially
lead to permission errors if a user sets it to a path *not* prepared in
the Dockerfile.

This PR proposes hardcoding the path in `docker-compose.yml` to
`/app/packages/twenty-server/.local-storage` to align with the
Dockerfile changes and simplify configuration. Is this acceptable, or is
there a specific use case for retaining the `STORAGE_LOCAL_PATH`
variable that needs to be considered? If retained, the Dockerfile would
need further changes to dynamically handle permissions based on this
variable.

**Impact:**

* Improves compatibility with deployment platforms that struggle with
run-once containers.
* Simplifies the `docker-compose.yml` setup (potentially, pending
discussion on `STORAGE_LOCAL_PATH`).
* Fixes volume permissions at the source (image build) rather than
relying on a runtime fix.
* Adds a warning for users who might have the potentially deprecated
variable set.

**Testing:**

The changes have been tested locally using `docker compose up`. The
services start correctly, the application is accessible, and the warning
message for the potentially deprecated variable appears as expected when
the variable is set.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-20 00:14:33 +02:00
PuruandGitHub 39fe7aa2a5 fix(docker-compose): increase retry for server service (#11883)
## Background
I'm trying to self-host twenty using [official 1-Click w/ Docker Compose
guide](https://twenty.com/developers/section/self-hosting/docker-compose)
on AWS EC2 (using `t3.small` instance type).

## What happened
I used the one-line script but it failed with
```
[skipped]
server-1                | Successfuly migrated DB!
dependency failed to start: container twenty-server-1 is unhealthy
```

Then I tried manual steps, and it failed again with same issue as above.
No configuration changed, everything default used.

I re-run manual steps multiple times with `docker compose down -v` and
`docker compose up`, everything time it failed with `server` unhealthy
as it seems server takes longer than configured health check duration
(which is 50 seconds)

Here's the `time` summary running it:
```
[skipped]
server-1                | Successfuly migrated DB!
dependency failed to start: container twenty-server-1 is unhealthy

________________________________________________________
Executed in   58.26 secs      fish           external
   usr time  661.43 millis  362.00 micros  661.07 millis
   sys time  646.10 millis  212.00 micros  645.89 millis

root@ip-10-0-10-43 ~/twenty [1]# 
```

## Why it happend

My hunch (new to twenty, just used it yesterday) is that server service
takes much longer to become healthy with DB migration and etc, that
configured health check retries is not sufficient.

## What solution worked

Increased the retry for server service from 10 to 20, and it worked and
service came up healthy (everytime). The increase wasn't needed for db
or worker service, just server service.

If this all makes sense, please feel free to merge this, so it'll be
smoother experience for others new to self-hosting twenty.
2025-05-20 00:04:38 +02:00
98e199c01d Support Full Name as Record Text Identifier (#11610)
closes #11296 


[recording.webm](https://github.com/user-attachments/assets/da0f2587-a435-4bee-a802-81eb9ca92733)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-20 00:03:30 +02:00
477a10ba4a close dropdown when model opens (#12060)
fixes #11900

changes desc:
1.moved confirmation model adjacent to dropdown component instead inside
it.
2.passing variables of useRecordGroupReorderConfirmationModal from
dropdown root component so confirmations model should remount get
updated with new state

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-05-19 23:46:40 +02:00
Abdul RahmanandGitHub 503aeee81f Fix/record board keyboard navigation empty columns (#12103)
https://github.com/user-attachments/assets/6830217b-28a9-46e6-a9f5-40d508cd262b

Closes #12077
2025-05-19 23:22:56 +02:00
Abdul RahmanandGitHub 42c69dd11a fix: Ensure attachment modal appears above Command Menu button using createPortal (#12112)
<img width="1509" alt="Screenshot 2025-05-19 at 12 50 48 AM"
src="https://github.com/user-attachments/assets/fba95ecb-015a-4742-bda2-4d515d168c16"
/>


Closes #12092
2025-05-19 23:08:31 +02:00
Lucas BordeauandGitHub 4f4f3a64fd Fix table re-renders on update or keyboard navigation (#12127)
This PR fixes the problem of full table re-render on any update or
keyboard navigation.

This was due to a recoil state subscribe in the RecordTable component, I
just moved it in the children effect components so that the Flux
dependency becomes inoffensive.

I also extracted one hook from the useRecordTable hook that we have to
refactor gradually.

Fixes https://github.com/twentyhq/core-team-issues/issues/979
Fixes https://github.com/twentyhq/core-team-issues/issues/932
2025-05-19 22:44:51 +02:00
85e2a2a92b fix: prevent unwanted newlines in note editor when typing (#12128)
https://github.com/user-attachments/assets/16706d7a-fe0e-4979-bd72-00f4bfec594b

Closes #12119

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-05-19 22:43:49 +02:00
Charles BochetandGitHub cba36af1e8 Fix dropdown (#12126)
In this PR:
- deprecating listenClickOutside ComparePixel mode as this is not
accurate. We were using to avoid portal issue with CompareHtmlRef mode
but this is still an issue when portalled content overflows the
container.
- add ClickOutsideContext to specify excluded className so portal
children can use it easily (part of the tooling)
- fix stories
- remove avoidPortal from dropdown as this was not used
2025-05-19 16:37:51 +02:00
WeikoandGitHub bb4fed5a5e Fix Identifier chips in Timeline Activities are broken (#12122)
Fixes https://github.com/twentyhq/twenty/issues/12114
Fixes https://github.com/twentyhq/core-team-issues/issues/856

Links were in the wrong format. This is because the timeline activity
code is re-using FieldDisplay which expects a context with a specific
recordId that we can't have (since this is not a true record but simply
the result of a diff and each row in the diff needs to be unique)
Today we build the artificial record ID like this `eventId + '--' +
fieldMetadataItem.id` to keep it unique.
However, in case the event concerns a labelIdentifier field, it uses the
ChipDisplay which creates a link to the record using the artificial ID
which results in a 404 when using the link.
We don't really need that link since it points to the record itself (the
one that is already opened) so I'm simply removing the
isLabelIdentifierField set in
[EventFieldDiffValue.tsx](https://github.com/twentyhq/twenty/compare/c--fix-identifier_chips_in_timeline_activities_are_broken?expand=1#diff-af17142141c5334214f43840460a142d531c61be7c3cff55bd8a495eb831bc69)
so even if it's one labelIdentifierField, it won't try to display it as
such.

Ideally we should refactor this logic and not try to reuse FieldDisplay
imho, we probably did that to avoid duplicating logic but that's a lot
of "fake" context to get the desired result

Before
<img width="423" alt="Screenshot 2025-05-19 at 15 23 46"
src="https://github.com/user-attachments/assets/b9573f4c-e205-4fdb-bdee-65b890da7810"
/>

After
<img width="428" alt="Screenshot 2025-05-19 at 15 23 33"
src="https://github.com/user-attachments/assets/96f29842-b9aa-4230-8125-dd7d1a56baed"
/>
2025-05-19 16:21:29 +02:00
Raphaël BosiandGitHub b70119dbe6 Fix modal click outside (#12120)
Fixes https://github.com/twentyhq/twenty/issues/12111

The bug occurred because in
https://github.com/twentyhq/twenty/pull/12062, I changed the click
outside mode of the modal from compare pixels to compare html ref. This
happens because the modal is in a portal, so the `compareHTMLRef`
doesn't work.

A bug already existed before but since the mode was compare pixel, it
only happened when a dropdown was overflowing from the modal:


https://github.com/user-attachments/assets/e34bfaca-dd21-46e5-a532-a66ba494889d

I commented the tests `CancelButtonClick`, and `ConfirmButtonClick`
because they don't work with compare pixel mode (the `userEvent.click()`
creates a `MouseEvent` with `clientX`=0 and `clientY`=0 so it triggers
the click outside listener even when the story tiggers a click on an
element inside a modal)

We should find a way to make the ClickOutsideMode `compareHTMLRef` work
with portals. I believe the `comparePixels` mode was used as a hacky way
to get around this problem (hacky because of the existing bug above).
2025-05-19 15:04:04 +02:00
EtienneandGitHub efc43208d3 add command to clean not found files (#12094)
closes https://github.com/twentyhq/core-team-issues/issues/883

tested on person, workspaceMember, workspace and attachments files -
dry/normal
2025-05-19 14:45:15 +02:00
MarieandGitHub a8753113a7 Fix aggregate operation update on dates on kanban views (#12115)
Fixes https://github.com/twentyhq/core-team-issues/issues/968
2025-05-19 13:19:38 +01:00
EtienneandGitHub 52ad789e7a fix billingCustomer stripeId fetching (#12116)
### Context
Several 'Customer not found' errors arrived in Sentry, all coming from
webhook-entitlement.service, at subscription creation (coinciding with
customer creation 99% of the time).
Stripe sends many events to update/create customer, subscription,
entitlement, ...
All these events are handle in parallel but customer.created stripe
event arrived first and few seconds after subscription.created and
entitlements.active_entitlement_summary.updated

Issue happens at entitlements.active_entitlement_summary.updated
handling. It checks for customer existence through subscription. But
subscription can be not created yet at this moment.

### Solution
Check directly for customer existence in billingCustomer table. Not sure
it will fix the error because of the parallel handling of Stripe event,
but should still be better.

### Tested
- Workspace creation
- Subscription upgrade (check for entitlement update)

closes https://github.com/twentyhq/twenty/issues/11960
2025-05-19 13:37:18 +02:00
martmullandGitHub b52ef76376 971 rest api bug sentry on filter parameters (#12088)
- fix missing createBy injection in api createOne and createMany
endpoints
- add a command to fix null default value for createdBySource in
production entities
- tested on `1747159401197/` dump extract of production db without issue
2025-05-19 12:46:03 +02:00
Lucas BordeauandGitHub 58b40b1f89 Removed value setter effect completely (#12101)
This PR removes the effect component that was synchronizing the record
store recoil state with the context selector equivalent state that is
used for performance on the tables.

Now we only set the context selector in parallel with the recoil state,
thus avoiding any synchronization side-effect between those two states.
2025-05-17 15:41:01 +02:00
Félix MalfaitandGitHub 64d988cdec Fix pg pool implementation (#12106)
Fix the following error: 
Cannot use a pool after calling end on a pool

<img width="917" alt="Screenshot 2025-05-17 at 14 56 18"
src="https://github.com/user-attachments/assets/63081831-9a7e-4633-8274-de9f8a48dbae"
/>

The problem was that the datasource manager was destroying the
connections when a datasource cache expired.
2025-05-17 15:22:10 +02:00
GuillimandGitHub d93024fd02 Refactoring the reconnect service (#12089)
following qrqc #3 : refactoring the reconnect service

Fixes https://github.com/twentyhq/twenty/issues/12064
2025-05-17 13:47:01 +02:00
e83baa5438 Patch pg pool (#12081)
This PR implements a global PostgreSQL connection pool sharing
mechanism.

- Patches pg.Pool to reuse connection pools across the application when
connection parameters match, reducing resource overhead.
- New environment variables allow enabling/disabling sharing and
configuring pool size, idle timeout, and client exit behavior.

WorkspaceDatasourceFactory will now use shared pools if enabled, this
will avoid recreating 10 connections for each pods for each workspace.

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-05-16 21:46:37 +02:00
Thomas TrompetteandGitHub eca5ef7cfe Fix composite field edition (#12095)
Fixes https://github.com/twentyhq/twenty/issues/12056

Bug has been introduced by
https://github.com/twentyhq/twenty/pull/11983/files

Adding onClick on the container makes it always available. Before it was
only when not in edit mode.
It breaks the click outside of the `RecordInlineCell`.

This PR set the onClick only when not in edit mode.



https://github.com/user-attachments/assets/a44337a9-72e6-4de8-afa1-95de6b953459
2025-05-16 18:58:32 +02:00
Raphaël BosiandGitHub e48b84f241 Fix hidden copy button on production build for text fields (#12099)
Fixes #11762

The `copy-button` classname from scalar was overwritting the style of
our copy button. It only happened in production build and not with `npx
nx run twenty-front:start` so it was quite hard to catch. Thanks
@charlesBochet for finding the root cause.

- Removed `copy-button` classname since it was unused
- Added `?inline` when importing scalar css to have inline css

Before:
<img width="210" alt="Capture d’écran 2025-05-16 à 17 43 50"
src="https://github.com/user-attachments/assets/7256b5e6-0b61-4590-a4de-d6b28ab2b4ed"
/>

After:
<img width="230" alt="Capture d’écran 2025-05-16 à 17 43 32"
src="https://github.com/user-attachments/assets/a763172b-0566-413d-bbdd-470f28097ae4"
/>
2025-05-16 18:29:42 +02:00
WeikoandGitHub 806bb611e8 Fix yoga scalar validations being captured (#12085)
Yoga graphql error were not correctly interpreted by the exception
handler. Mostly validations on the scalars such as bad enum options,
wrong format for uuid and such.
This PR adds a new convertGraphQLErrorToBaseGraphQLError utility
function in graphql-errors.util.ts that converts those errors to our
custom BaseGraphQLError by using the extension.http.code from the error
when possible so they can be handled the same way we treat the graphql
errors we throw ourselves.

Before
<img width="799" alt="Screenshot 2025-05-16 at 11 04 08"
src="https://github.com/user-attachments/assets/08b0a908-34d8-45a6-b315-8e211d1104ce"
/>

After
<img width="797" alt="Screenshot 2025-05-16 at 11 16 37"
src="https://github.com/user-attachments/assets/3fff0a70-6c3f-413a-b458-56030377fec9"
/>
2025-05-16 18:11:52 +02:00
Paul RastoinandGitHub 6823224177 [DOCS] A Note about audit log removal in 0.53 upgrade (#12097)
# Introduction

Please see related added docs
2025-05-16 15:18:11 +00:00
Raphaël BosiandGitHub 455615b14c Fix drag selection on table make rows bigger (#12096)
Fixes [#12036](https://github.com/twentyhq/twenty/issues/12036)
2025-05-16 17:15:24 +02:00
Raphaël BosiandGitHub 6554947671 Modal API Refactoring (#12062)
# Modal API Refactoring

This PR refactors the modal system to use an imperative approach for
setting hotkey scopes, addressing race conditions that occurred with the
previous effect-based implementation.

Fixes #11986
Closes #12087

## Key Changes:

- **New Modal API**: Introduced a `useModal` hook with `openModal`,
`closeModal`, and `toggleModal` functions, similar to the existing
dropdown API
- **Modal Identification**: Added a `modalId` prop to uniquely identify
modals
- **State Management**: Introduced `isModalOpenedComponentState` and
removed individual boolean state atoms (like
`isRemoveSortingModalOpenState`)
- **Modal Constants**: Added consistent modal ID constants (e.g.,
`FavoriteFolderDeleteModalId`, `RecordIndexRemoveSortingModalId`) for
better maintainability
- **Mount Effects**: Created mount effect components (like
`AuthModalMountEffect`) to handle initial modal opening where needed

## Implementation Details:

- Modified `Modal` and `ConfirmationModal` components to accept the new
`modalId` prop
- Added a component-state-based approach using
`ModalComponentInstanceContext` to track modal state
- Introduced imperative modal handlers that properly manage hotkey
scopes
- Components like `ActionModal` and `AttachmentList` now use the new
`useModal` hook for better control over modal state

## Benefits:

- **Race Condition Prevention**: Hotkey scopes are now set imperatively,
eliminating race conditions
- **Consistent API**: Modal and dropdown now share similar patterns,
improving developer experience

## Tests to do before merging:

1. Action Modals (Modal triggered by an action, for example the delete
action)

2. Auth Modal (`AuthModal.tsx` and `AuthModalMountEffect.tsx`)
   - Test that auth modal opens automatically on mount
   - Verify authentication flow works properly

3. Email Verification Sent Modal (in `SignInUp.tsx`)
   - Verify this modal displays correctly

4. Attachment Preview Modal (in `AttachmentList.tsx`)
   - Test opening preview modal by clicking on attachments
   - Verify close, download functionality works
   - Test modal navigation and interactions

5. Favorite Folder Delete Modal (`CurrentWorkspaceMemberFavorites.tsx`)
   - Test deletion confirmation flow
- Check that modal opens when attempting to delete folders with
favorites

6. Record Board Remove Sorting Modal (`RecordBoard.tsx` using
`RecordIndexRemoveSortingModalId`)
- Test that modal appears when trying to drag records with sorting
enabled
   - Verify sorting removal works correctly

7. Record Group Reorder Confirmation Modal
(`RecordGroupReorderConfirmationModal.tsx`)
   - Test group reordering with sorting enabled
   - Verify confirmation modal properly handles sorting removal

8. Confirmation Modal (base component used by several modals)
   - Test all variants with different confirmation options

For each modal, verify:
- Opening/closing behavior
- Hotkey support (Esc to close, Enter to confirm where applicable)
- Click outside behavior
- Proper z-index stacking
- Any modal-specific functionality
2025-05-16 15:04:22 +00:00
nitinandGitHub 8334fe9528 Add placeholder to signinup modal's secondary logo (#12079)
closes https://github.com/twentyhq/core-team-issues/issues/972

checks - 

- [x]  If we have an icon it should be displayed as `secondary`

<img width="1064" alt="Screenshot 2025-05-16 at 00 33 42"
src="https://github.com/user-attachments/assets/20716df3-28be-40c5-b0fc-2133fccdad83"
/>

- [x] If no icon is provided, display a placeholder

<img width="1062" alt="Screenshot 2025-05-16 at 00 33 09"
src="https://github.com/user-attachments/assets/0241dafe-3d31-4f8e-a9e4-321634f6d41c"
/>

- [x] Add story for auth logos
<img width="550" alt="Screenshot 2025-05-16 at 16 16 24"
src="https://github.com/user-attachments/assets/3859547d-32c5-469f-879b-a130a36a23fa"
/>

<img width="548" alt="Screenshot 2025-05-16 at 16 16 30"
src="https://github.com/user-attachments/assets/4937fa6a-459a-4c75-86ae-2080b1c8a5ae"
/>

<img width="487" alt="Screenshot 2025-05-16 at 16 16 16"
src="https://github.com/user-attachments/assets/2c634be1-4a51-4b06-a590-cdd7eff91b76"
/>

<img width="556" alt="Screenshot 2025-05-16 at 16 16 07"
src="https://github.com/user-attachments/assets/e4a518b4-c338-45c1-a329-5c9f85319c52"
/>
2025-05-16 14:21:24 +00:00
4017bd48f7 Update SettingsFieldCurrencyCodes.ts — XOF Currency (#12047)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-16 12:09:41 +02:00
EtienneandGitHub 160eb23454 QRQC #2 - Fix (#12054)
- [x] findOne/findManyCalendarEvents / findOne/findManyMessages - add
integration tests
- [ ] ~~fix typing~~ - coming in new PR >
[Issue](https://github.com/twentyhq/core-team-issues/issues/976)
2025-05-16 11:38:34 +02:00
MarieandGitHub dc4bcc3049 Improve sentry filtering and grouping (#12071)
Follow-up on https://github.com/twentyhq/twenty/pull/12007

In this PR

- adding a filter on HttpExceptionHandlerService to filter out 4xx
errors from driver handling (as we do for graphQL errors: see
useGraphQLErrorHandler hook - only filteredIssues are sent to`
exceptionHandlerService.captureExceptions()`.)
- grouping together more missing metadata issues
- attempting to use error codes as issues names in sentry to improve UI;
for now it says "Error" all the time
2025-05-16 11:35:48 +02:00
Félix MalfaitandGitHub 4d303a61d1 Change idle connection time (#12073)
As discussed with @Weiko

Even though we cache the datasource, the connection expire after
10minutes in TypeORM, that might be the reason why our app is spamming
the proxy asking for connections. Also lowering the pool size.
2025-05-15 19:23:51 +00:00
Antoine MoreauxandGitHub 1570ad955e fix(domain-manager): correct domain URL reference and filter logic (#12074)
Updated URL reference from getFrontUrl to getBaseUrl to ensure correct
hostname handling. Adjusted record filtering logic to exclude successful
records, preventing unnecessary rendering in the UI.
2025-05-15 19:35:55 +02:00
Lucas BordeauandGitHub 09d92c9113 Fixes infinite loop on record data update in command menu (#12072)
This PR fixes the infinite loop that was happening in `RecordShowEffect`
component due to a useEffect on `recordStoreFamilyState` which was
creating a non-deterministic open loop.

The fix was to use a recoilCallback to avoid reading a stale state from
Recoil with `useRecoilValue`, useRecoilCallback always gets the most
fresh data and commits everything before React goes on with rendering,
thus avoiding any stale value in a useEffect.

Fixes https://github.com/twentyhq/twenty/issues/11079
Fixes https://github.com/twentyhq/core-team-issues/issues/957
2025-05-15 18:26:01 +02:00
Paul RastoinandGitHub 442f8dbe3c [QRQC_2] No implicitAny in twenty-server (#12075)
# Introduction
Following https://github.com/twentyhq/twenty/pull/12068
Related with https://github.com/twentyhq/core-team-issues/issues/975

We're enabling `noImplicitAny` handled few use case manually, added a
`ts-expect-error` to the others, we should plan to handle them in the
future
2025-05-15 18:23:22 +02:00
martmullandGitHub 08ce2f831e Fix missing exception catch (#12069)
add a check about uuid in rest api findOne handler
2025-05-15 15:01:57 +00:00
a8423e8503 [QRQC_2] No explicit any in twenty-server (#12068)
# Introduction

Added a no-explicit-any rule to the twenty-server, not applicable to
tests and integration tests folder

Related to https://github.com/twentyhq/core-team-issues/issues/975
Discussed with Charles

## In case of conflicts
Until this is approved I won't rebased and handle conflict, just need to
drop two latest commits and re run the scripts etc

## Legacy
We decided not to handle the existing lint error occurrences and
programmatically ignored them through a disable next line rule comment

## Open question
We might wanna activate the
[no-explicit-any](https://typescript-eslint.io/rules/no-explicit-any/)
`ignoreRestArgs` for our use case ?
```
    ignoreRestArgs?: boolean;
```

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-05-15 16:26:38 +02:00
GuillimandGitHub c95c4383b4 Gmail temporary error (#12058)
# Handling Google error

This bug is hard to reproduce so the resolution is based only on the
Sentry logs. There is not definite error code
for this error message. in the documentation.
https://developers.google.com/workspace/gmail/api/guides

This is why i added more 5xx code types in order to be sure we catch
this. In order to refine this later, i added the error code to the
message.

Fixes https://github.com/twentyhq/twenty/issues/12025
2025-05-15 16:12:10 +02:00
MarieandGitHub f782f4dcd8 Fix CSV import upsert (#12048)
Fixes https://github.com/twentyhq/twenty/issues/11864 and
https://github.com/twentyhq/core-team-issues/issues/908

We should not send `createManyXXX` mutations with FE-forged ids in the
payload if we want to do an upsert, because that 1) prevents records
from being merged 2) triggers optimistic rendering while we can't know
before-hand which records will actually be created and which records
will only be updated

Also noticed createdBy was being overriden even for records we are
updating and not creating, which did not seem right, so fixed that too
2025-05-15 14:44:31 +02:00
Thomas TrompetteandGitHub aa424c6680 Make workflow custom fields editable (#12063)
Fixes https://github.com/twentyhq/twenty/issues/11989

<img width="1267" alt="Capture d’écran 2025-05-15 à 14 05 15"
src="https://github.com/user-attachments/assets/fbb22f52-2c76-424f-8b8c-fb030fef9fa8"
/>

`isCustom` was not properly set everywhere because it was not mandatory
in `isFieldValueReadOnly`. Removing the default value and adding it to
missing places
2025-05-15 12:28:13 +00:00
GuillimandGitHub 411cb33137 [reconnect account] Reseting calendar status and stage on reconnect (#12061)
## Description
When a calendar channel fails, its status is not reset during the
reconnect step.

In some cases, resetting is necessary—especially when we’ve deployed a
fix and users try to reconnect their accounts after the patch.

## Why reseting to initial state
Our processes are idempotent, so we can safely set the status to null to
restart the flow. This approach covers all cases and avoids edge
conditions caused by inconsistent statuses.


Fixes : https://github.com/twentyhq/twenty/issues/12026
2025-05-15 14:12:32 +02:00
3a494905ec Fixed error with previous filters on ACTOR with new sub-field filtering (#12050)
Fixes https://github.com/twentyhq/core-team-issues/issues/969 that
appeared since the new ACTOR sub-field filtering that changed the
default sub-field filtering from name to source.

Now we apply any existing filter value on an ACTOR field, whether for a
sub-field or not, to the name sub-field by default.

If the user wants to create a sub-field filter on source, he has to
create a new advanced filter.

Fixes https://github.com/twentyhq/core-team-issues/issues/967

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-05-15 13:58:22 +02:00
nitinandGitHub 93c91c88dc Exclude workflows from relation field object dropdown when inactive (#12033)
closes #11996
- Switched the “Object destination” select in
SettingsDataModelFieldRelationForm to use
activeObjectMetadataItems.filter(...) so workflows, system, and remote
objects are excluded
- Updated useRelationSettingsFormInitialValues to fall back on the same
filtered activeObjectMetadataItems list for its initial value

This ensures workflows (and any unwanted system/remote objects) no
longer show up in the dropdown or as the default.
2025-05-15 17:04:10 +05:30
Thomas TrompetteandGitHub 6a40ec604c Validate existing fields on creation (#12057)
Fixes https://github.com/twentyhq/twenty/issues/12040

When fields are deleted but still used in workflows we do not update
create record action settings.
It breaks all following workflow execution and the user cannot update
the settings anymore.

This PR fixes the bug by filtering on existing fields.

Next step will be to clean settings on field deletion. Adding it to fast
follows.

Also lowering throttle limit because some infinite loops are not
catched.
2025-05-15 13:24:57 +02:00
Lucas BordeauandGitHub 9e00a67b25 Fix kanban loading bug (#12042)
Fixes https://github.com/twentyhq/core-team-issues/issues/956

This PR fixes a bug that appeared when switching between two kanban
views multiple times.

Steps to reproduce : 
- Go to kanban view A
- Go to kanban view B
- Go back to kanban view A

Video before : 


https://github.com/user-attachments/assets/4fa789ae-7187-498e-82b4-ee7896cd95d1

Video after : 


https://github.com/user-attachments/assets/2b323a2d-2f76-405d-9abd-38fe72ee2214

The problem was that we allowed a hook to take a nullable parameter that
can be nullable between page switch, and threw when it was undefined.

In order to be more cautious in the future, let's be sure that we don't
throw for undefined props of a hook, when it is expected that those
props can be in an undefined state for several React render loops, while
fetching new data.

Here I identified the parent effect : `<RecordIndexBoardDataLoader />`
that loads all states for a board when we switch between views, for each
column, by calling `<RecordIndexBoardColumnLoaderEffect />` in a
`.map()`.

Each `RecordIndexBoardColumnLoaderEffect` was calling
`useLoadRecordIndexBoardColumn` with a potentially undefined
`boardFieldMetadataId`.

So to fix this, I cut the render flow higher than the throw in
`useLoadRecordIndexBoardColumn`, and by doing that I was able to ensure
that `recordIndexKanbanFieldMetadataItem` in
`RecordIndexBoardDataLoader` was already defined when using it inside
`useLoadRecordIndexBoardColumn`.

`recordIndexKanbanFieldMetadataItem` was unnecessarily fetched two
times, one time in `RecordIndexBoardDataLoader` and another time in its
child `useLoadRecordIndexBoardColumn` hook.

By implementing this flow-cut higher up, I could then remove the `|
null` in TypeScript in children components, and expect a defined value
in all the children of `RecordIndexBoardDataLoader`, thus removing the
need to ask ourselves if we should throw or not in
`useLoadRecordIndexBoardColumn`.
2025-05-15 10:27:47 +02:00
nitinandGitHub 52c38c3082 Correct default fallback logo path in Logo component (#12053)
closes #11849
The Logo component’s fallback URL was pointing to
`/icons/android/android-launchericon-192-192.png`, but the asset lives
under `/images/icons/....`. This updates defaultPrimaryLogoUrl to use
the correct `/images/icons/android/android-launchericon-192-192.png`
path, restoring the default logo display when no primaryLogo prop is
provided.
2025-05-15 09:44:37 +02:00
martmullandGitHub 81cc5da982 [Rest Api] Fix find duplicates endpoint (#12044)
- fix endpoint
- migrate to new rest api v2 service
- add integration test
2025-05-14 20:03:59 +00:00
GuillimandGitHub fdc7d6c93c Messaging issues (#12041)
messageImportException
for messaging and calendar
add more context to the Sentry Exceptions

Fixes https://github.com/twentyhq/twenty/issues/11994
2025-05-14 18:37:42 +02:00
Lucas BordeauandGitHub 628ba18115 Fix infinite loop critical bug (#12046)
This PR fixes an infinite loop than happens due to a useEffect in a non
deterministic manner.

The fix is to put a `isDeeplyEqual()` to avoid re-rendering the
useEffect if the value is the same.

Fixes : https://github.com/twentyhq/core-team-issues/issues/957
2025-05-14 17:40:05 +02:00
EtienneandGitHub 929f7876de fix calendar events and messages post hooks (#12034)
Context
workspaceMemberId is not always present in AuthContext. Solution
implemented here is to fetch workspaceMemberId via userId.

QRQC coming ... 

Tested
- FindManyCalendarEvents / FindOneCalendarEvent
- FindManyMessages / FindOneMessage

closes https://github.com/twentyhq/twenty/issues/12027
2025-05-14 15:52:52 +02:00
MarieandGitHub 0c60fa9c23 Fix cacheData not found after recomputes (#12032)
Closes https://github.com/twentyhq/core-team-issues/issues/861

sentries: [User workspace role map not found after
recompute](https://twenty-v7.sentry.io/issues/6575092700/events/f9825338a30b470eb2345fe78c1e3479/?project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D%20not%20found%20after%20recompute&referrer=next-event&stream_index=0)
(64 events in 90d), [Feature flag map not found after
recompute](https://twenty-v7.sentry.io/issues/6547696076/?project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D%20not%20found%20after%20recompute&referrer=issue-stream&stream_index=1)
(23 events in 90d)

We have a structural issue with cached data and our locking mechanism:
if a data is missing in cache and queried at the same time by two
different entities, the first one will recompute the data and indicate a
lock during the operation, while the second one will seek to recompute
the data too but be stopped because of the ongoing lock, and be left
with no data to use, condemned to throw an error. In this PR I
considered that it was more important to avoid that error and chose to
ignoreLock instead when the data is being queried (through
getFromCacheWithRecompute), but this is maybe questionnable.
An important note is that I can't figure out how users that regularly
use twenty (as it has been the case since this error occured on our
internal workspace) can encounter that error as once computed, **the key
should always be present in the workspace**: the corresponding value it
is always updated, never deleted (until this PR) and recreated. I was
not able understand how this happened

For our data cached without a version to refer to in the database, I
also chose to ignore the lock when the recompute is triggered by a data
change (eg feature flag enabling or assigning user to a role or adding
an objectPermission on a role, etc.), as we never want to imped the
recompute in that case to avoid potential stale data.
2025-05-14 15:41:24 +02:00
Paul RastoinandGitHub 83bdb1a515 [DOCS] New troubleshoot password authentication failed for user "postgres" (#12031)
# Introduction
Shorter and clearer issue
https://github.com/twentyhq/twenty/issues/11868
close https://github.com/twentyhq/twenty/issues/8701
2025-05-14 15:17:06 +02:00
Raphaël BosiandGitHub 8ef9109925 Fix table click outside (#12038)
Fixes #12037 
Follow up on #12011

Make `RecordTableBodyFocusClickOutsideEffect` also be available for
`RecordIndexHotkeyScope.RecordIndex`
2025-05-14 13:08:06 +00:00
martmullandGitHub a4c56bd7fb 960 api rest batch create not working (#12028)
- fix batch endpoint
- migrate batch endpoint to the rest api v2
- add new integration test for batch endpoints
2025-05-14 14:44:04 +02:00
Raphaël BosiandGitHub 0766e73fc4 Fix filtering on grouped table view (#12029)
# Fix filtering on grouped table view

Fixes #11776 
This PR fixes the filtering issue on the grouped by column in the table.
State filters were overwritten by group filters.

- Implemented a new `combineFilters` utility function that properly
merges multiple filter objects using AND logic
- Added tests
- Modified `useFindManyRecordIndexTableParams` to use the new utility
instead of directly merging filter objects

## Before


https://github.com/user-attachments/assets/45d51535-ecbc-4cfd-b523-37e72aafc723


## After


https://github.com/user-attachments/assets/70416779-9a9c-4972-82ed-73ad98b0234f
2025-05-14 13:30:37 +02:00
nitinGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix Malfait
2aa5db580b fix 11997 (#12018)
addressing:
https://github.com/twentyhq/twenty/issues/11997#issuecomment-2875772322
<img width="922" alt="Screenshot 2025-05-13 at 22 52 28"
src="https://github.com/user-attachments/assets/dc3b5fdd-b81b-4732-94f3-2ef2eb0012c2"
/>
before: 


https://github.com/user-attachments/assets/b55bf77e-99bf-485f-bcfa-5d311e7d2bd0

after: 


https://github.com/user-attachments/assets/70fb80b2-ce9f-4a8a-ac5d-d8c793c023be

### Some other issues I found

- On clicking clear, nothing happens

Before:


https://github.com/user-attachments/assets/01e937bb-b4d4-4296-baa7-ec1602de2cc9

After:


https://github.com/user-attachments/assets/8e4e5022-fe32-44fe-a7e4-5c98a7f3c2fa


- same behaviour for inline cell DateInput: 


https://github.com/user-attachments/assets/787354e5-b50a-457c-a392-4779270e2832


### Notes
The root issue seems to be that ViewBarFilterDropdown sets a fixed width
of 208px, which isn’t enough for the calendar to render correctly - it
ends up cropping the content. The fix here is more of a workaround than
a deep fix: I’ve adjusted styles to avoid the cropping, but it might be
worth revisiting how we handle sizing for filter dropdowns in general.

cc @lucasbordeau - thoughts?
Related commit:
https://github.com/twentyhq/twenty/commit/afea017c127b5055ead5170873636c0e81953898

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-14 16:35:51 +05:30
9c2b88870f Improve sentry grouping (#12007)
This PR attemps at improving sentry grouping and filtering by 
- Using the exceptionCode as the fingerprint when the error is a
customException. For this to work in this PR we are now throwing
customExceptions instead of internalServerError deprived of their code.
They will still be converted to Internal server errors when sent back as
response
- Filtering 4xx issues where it was missing (for emailVerification
because errors were not handled, for invalid captcha and billing errors
because they are httpErrors and not graphqlErrors)

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-14 09:00:06 +00:00
Jordan ChalupkaandGitHub 6a1da5fe53 Make the default view names consistent (#12022) (#12023)
Fixes #12022

## What changed

Now the default names given to views are consistent for People,
Companies and Opportunities

## Before

Some say "All", others say "Some {object name}"


![Image](https://github.com/user-attachments/assets/4233f793-55e1-4566-b9b3-08a6f136dd53)


![Image](https://github.com/user-attachments/assets/29b1af5c-487e-4593-ba40-86163b518ca7)


![Image](https://github.com/user-attachments/assets/81fc1933-0e13-4144-914e-0d99a44db8e4)


![Image](https://github.com/user-attachments/assets/9439fc64-e6e0-4a04-ba28-13c3954a1aa1)

## After


![Image](https://github.com/user-attachments/assets/e88288ac-3a41-4810-bb2a-8e91c937ed6c)


![Image](https://github.com/user-attachments/assets/8fc353e3-5a7c-42ac-88d3-b7014c0fd02c)
2025-05-14 10:44:14 +02:00
martmullandGitHub 4d2e431277 959 api rest startingafter and endingbefore not working properly with orderby (#12012)
Fixes https://github.com/twentyhq/core-team-issues/issues/959
2025-05-14 10:41:56 +02:00
Raphaël BosiandGitHub e835e0ad64 Fix UI not being refreshed after grouping by None in the table (#12013)
Fixes https://github.com/twentyhq/twenty/issues/11719

Before:


https://github.com/user-attachments/assets/9350d20c-e782-4bf4-9e24-bc7dd7f3d03b


After:


https://github.com/user-attachments/assets/d452fd54-63f7-4519-b70f-5c380b7dd8da
2025-05-14 08:14:19 +00:00
nitinandGitHub fcac7b8a40 docs: update admin panel access property name in upgrade guide (#12019)
## Changes
- Updated the property name in the upgrade guide to reflect the
permission split in Admin Panel:
  - `canImpersonate`: only provides access to impersonate functionality
- `canAccessFullAdminPanel`: provides access to all other admin panel
features
2025-05-13 21:59:43 +02:00
c0b2d400d8 [DRAFT]: Add full Dev Workspace seeding to Preview Env Keep-Alive workflow (#12020)
does this work?

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-13 21:58:36 +02:00
Charles BochetandGitHub 0202586d36 Fix message channel processing (#12021)
Several users have complained about not being able to read their emails
anymore.

This is because the find-messages post query hook is expecting
ObjectRecord[] as an input but is actually getting a graphql Connection

Typing was wrong. This PR fixes the typing and make sure the post query
hook always get an ObjectRecord[]
2025-05-13 21:16:23 +02:00
EtienneandGitHub c0a0214879 delete attachment when file is removed from activity body (#11952)
Using useEffect triggered at ActivityRichTextEditor unmount, to delete
attachments only when note is closed (and not when file block is deleted
during note update to keep command + z shortcut)

closes : https://github.com/twentyhq/twenty/issues/11229
2025-05-13 19:18:38 +02:00
Paul RastoinandGitHub 3fe9c79967 docs(website): fix typos (#12016) 2025-05-13 19:16:44 +02:00
Paul RastoinandGitHub 6ac82b9591 [DOCS] Upgrade guide 0.53 (#12015) 2025-05-13 18:35:09 +02:00
Baptiste DevessierandGitHub fc4d313907 Remove duplicated position for task's status field (#11998)
In this PR:

- Set the default position for the DONE option of the task's status
option to `2` instead of `1`, which was the same as `IN_PROGRESS`
option's position.
- Write a command to prevent position duplicates in the database for the
task's status field.

What I've checked before setting this PR as ready to be reviewed:

- De-duplicating the position solves the issue and it's possible to edit
the field (solves the related issue)
- The upgrade command de-duplicates the position for each workspace.
There are no more DONE options with `position=2`. I ran the upgrade
command on the `database-snapshot-manager` dataset.
- Suspended workspaces aren't fixed

---

To test the script:

```ts
const scannedPositions = new Set();
let biggestPosition = -1;

// Sort options by position for consistent processing
const sortedOptions = [
  { name: 'a', position: 2 },
  { name: 'b', position: 1 },
  { name: 'c', position: 1 },
  { name: 'd', position: 2 },
].sort((a, b) => a.position - b.position);

for (const option of sortedOptions) {
  if (scannedPositions.has(option.position)) {
    option.position = biggestPosition + 1;
  }

  biggestPosition = Math.max(biggestPosition, option.position);
  scannedPositions.add(option.position);
}

console.log('Sorted options:', sortedOptions);
```

Closes https://github.com/twentyhq/twenty/issues/11790
2025-05-13 16:21:47 +00:00
Raphaël BosiandGitHub dfe8011948 Fix side panel click outside (#12011)
Fixes https://github.com/twentyhq/twenty/issues/11988

## Description

The issue came from `RecordTableBodyFocusClickOutsideEffect`.
When clicking outside the table with the side panel opened, two click
outside listeners were triggered: the one which closes the side panel
and the one which leaves the table focus. There was a race condition and
the leave table focus was executed first, changing the hotkey scope. The
side panel closure wasn't executed because the hotkey scope was wrong.

## Fix
Only leave the table focus if the hotkey scope is `TableFocus`


## Videos

Before:


https://github.com/user-attachments/assets/0ea666a6-c212-4b94-b89b-49211d18a13b


After:


https://github.com/user-attachments/assets/2ec6d593-ff65-4cbf-ac92-a0cfbd7dfd8b
2025-05-13 17:56:04 +02:00
Félix MalfaitandGitHub 3efdbed5d1 Fix clickhouse connection 2 (#12010)
Revert changes in #12006 as it might still be handy to have the DB
auto-created (e.g. for test or self-hosting users), but if there is a
permission exception we will just ignore it and assume the database
exist in that case
2025-05-13 16:52:07 +02:00
cec381c4de i18n - translations (#12009)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-13 16:26:27 +02:00
Charles BochetandGitHub e94d90894b Fix relation deletion (#12008)
## What
This PR fixes a regression tied to the new relation format refactoring.
I'm also slightly improving the performance by decreasing the number of
queries.

## Considerations
1. I've started adding an integration test to cover relation creation
and deletion but we are still using the r`elation-metadata.service` to
create a relation and the `field-metadata.service` to delete it. As we
plan to fully deprecate the `relation-metadata.service`, I did not want
to invest into writing test tooling to change it in a few weeks so I've
reverted the test

2. We are still maintaining relationMetadata table up-to-date (so
deleting them when we delete the field). relationMetadata full
deprecation is up coming but I'm waiting a bit so we don't have breaking
changes in 0.53
2025-05-13 16:22:59 +02:00
EtienneandGitHub bed33b00b9 adapt billing banners according to user's permissions (#12005)
closes https://github.com/twentyhq/twenty/issues/11951
2025-05-13 16:18:57 +02:00
Félix MalfaitandGitHub fb615ed201 Remove clickhouse check requiring elevated permissions (#12006)
This check was un-necessary, it will fail after in anycase. Let's leave
it to the user to create the DB
2025-05-13 15:36:55 +02:00
Ajay A AdsuleandGitHub efffac2a1a Deleted view disable delete btn (#11990)
This PR updates the defaultRecordActionConfig for the
SingleRecordActionKeys.DELETE action. A condition
!isSoftDeleteFilterActive was added to the shouldBeRegistered function
to ensure the delete button is only visible when the deleted records
view is not selected.

This prevents the delete button from appearing when viewing deleted
records.

#11974  

![Screenshot 2025-05-12 at 9 41
30 PM](https://github.com/user-attachments/assets/ab7c1f61-d5ab-4315-9f39-50108d11438c)

![Screenshot 2025-05-12 at 9 42
11 PM](https://github.com/user-attachments/assets/82a9843b-4d5e-406c-8186-dce5b7b16bf3)
2025-05-13 14:00:15 +02:00
Charles BochetandGitHub 45d4845b26 Remove old relations (#11993)
This is a first PR to remove old relation logic

Next steps:
- remove relationMetadata from cache
- remove relationMetadata table content and structure
- refactor relationDefinition to leverage field.settings instead
2025-05-13 11:28:22 +02:00
9ed6edc005 Twenty config integration tests + conversion refactor (#11972)
- In this PR the default value of IS_CONFIG_VARIABLES_IN_DB_ENABLED has
been changed to true,
    
- This is my first time writing integration tests, so I’d appreciate a
thorough review. :)
I’ve tried to follow the existing test patterns closely, but there might
be some small mistakes I may have missed.
Also let me know if I have missed any important test cases that should
be tested

UPDATE - 
### Config Value Converter Refactoring
- Created a centralized type transformers registry with bidirectional
validation
- Refactored ConfigValueConverterService to support validation in both
directions:
- Maintained existing DB-to-app conversion behavior
- Added validation for app-to-DB conversion
- Added integration tests to verify validation works in both directions

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-13 13:34:27 +05:30
Lucas BordeauandGitHub df3db85f7f Implemented LINKS and EMAILS sub-field fitering (#11984)
This PR introduces LINKS and EMAILS sub-field filtering. It's mainly
about the implementation of secondaryLinks and additionalEmails
sub-fields, which are treated like additionalPhones.

There's also a refactor on the computeViewRecordGqlOperationFilter, a
big file that becomes very difficult to read and maintain. This PR
breaks it down into multiple smaller utils. There's still work to be
done to clean it as it is a central part of the record filter module,
this PR lays the foundation.
2025-05-12 21:30:53 +02:00
Paul RastoinandGitHub 0fb5ea7d06 Sync-metadata swallow FK_e078063f0cbce9767a0f8ca431d (#11991)
# Introduction
Encountering a blocking issue due to legacy upgrade history in staging
due to relation refactor
For the moment ( release 0.53 ) swallowing
@charlesBochet 

## How to test
```ts
checkout v0.52.11
yarn
database:reset
checkout 0.53
yarn
build server
migrate
upgrade
```
2025-05-12 17:14:45 +00:00
Raphaël BosiandGitHub 4d352cb4e4 Keyboard Navigation and Shortcuts Implementation on the board (#11930)
# Keyboard Navigation and Shortcuts Implementation on the board

This PR implements keyboard navigation and shortcuts for the Record
Board component, enabling users to navigate and interact with board
cards using keyboard inputs.

## Key changes

### Navigation Architecture
- Added `useBoardCardNavigation` hook for directional navigation (arrow
keys)
- Implemented scroll behavior to automatically focus visible cards
- Created card focus/active states with component-level management

### State Management
- Added new component states: `focusedBoardCardIndexesComponentState`,
`activeBoardCardIndexesComponentState`,
`isBoardCardActiveComponentFamilyState`
- Extended index tracking with column/row position indicators
- Create hooks to manage these states

### Hotkey Implementation
- Created new `RecordBoardHotkeyEffect` component for hotkey handling
- Added `BoardHotkeyScope`
- Implemented Escape key handling to clear selections
- Replaced table-specific `TableHotkeyScope` with more generic
`RecordIndexHotkeyScope`. This is because, before, the hotkey scope was
always set to Table inside the page change effect, and we used the table
hotkey scope for board shortcuts, which doesn't make a lot of sense.
Since we don't know upon navigation on which type of view we are
navigating, I introduced this generic hotkey scope which can be used on
the table and on the board.

### Page Navigation Integration
- Modified `PageChangeEffect` to handle both table and board view types
- Added cleanup for board state upon navigating away from record pages

### Component Updates
- Updated `RecordBoardColumn` to track indexes for position-based
navigation
- Added `RecordBoardScrollToFocusedCardEffect` for auto-scrolling to
focused cards
- Added `RecordBoardDeactivateBoardCardEffect` for cleanup

This implementation maintains feature parity with table row navigation
while accounting for the 2D navigation needs of the board view.

## New behaviors

### Arrow keys navigation


https://github.com/user-attachments/assets/929ee00d-2f82-43b9-8cde-f7bc8818052f


### Record selection with X


https://github.com/user-attachments/assets/0b534c4d-2865-43ac-8ba3-09cb8c121f06


### Command + Enter opens the record


https://github.com/user-attachments/assets/0df01d1c-0437-4444-beb1-ce74bcfb91a4


### Escape unselect the records and unfocus the card



https://github.com/user-attachments/assets/e2bb176b-b6f7-49ca-9549-803eb31bfc23
2025-05-12 19:02:14 +02:00
Charles BochetandGitHub 4e39ef832c Fix 0.53 upgrade commands (#11987)
In this PR:
- fixes
[0-53-upgrade-search-vector-on-person-entity.command.ts](https://github.com/twentyhq/twenty/pull/11987/files#diff-d97fb2aefe44ac5d849fb7e29b8eaa1ca7c0f109d1b43fbdf87723b05dd22f58)
small mistake
- adding Cascade DELETE on fieldMetadata.relationTargetObjectMetadataId
(like we have on fieldMetadata.objectMetatadaId)
- enabling IsNewRelationEnabled in 0.53 upgrade
2025-05-12 17:26:35 +02:00
a942642b83 Untitled records for CreatedBy (#11914)
# Display "Soft-Deleted Workspace Members" in Actor Field Display

Reminder of the issue :
<img width="154" alt="Screenshot 2025-05-07 at 12 11 59"
src="https://github.com/user-attachments/assets/168f8743-2684-4d9a-b1a4-e86bb335f7a4"
/>

- `ActorFieldDisplay` component : display soft-deleted members
- `UserService` includes soft-deleted records when fetching workspace
members. This is the tricky part : do we want that for all workspace
members or maybe i could create another property dedicated to workspace
members and softdeleted ones. To be discussed

Result looks like this (we loose the source and the context in this
impleentation)
<img width="114" alt="Screenshot 2025-05-07 at 12 05 28"
src="https://github.com/user-attachments/assets/3cdddd91-454f-4e96-8d6d-6fe671658945"
/>


Fixes https://github.com/twentyhq/twenty/issues/11870


Another way we could also get into :
We could also, when a workspace user is softDeleted, change the current
implementation : we could avoid to delete the ActorMetadata like
CreatedByName (and context and source) in the "Person" table.

It would look more like this
<img width="111" alt="Screenshot 2025-05-07 at 12 06 16"
src="https://github.com/user-attachments/assets/daa4ece2-200a-41f0-ba24-177375c72983"
/>

However, this implementation is requires more work, and IMO harder to
maintain since is decouples completely the record from the workspace
member. This could be an issue in case we want tohard delete a user, or
decide another logic to display the Actor name.

Since the usecase should be pretty rare, I chose the first one but
willing to discuss it

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-05-12 15:54:56 +02:00
EtienneandGitHub 679530020c increase recordCard field hovering zone width + click (recordCard and summaryCard) (#11983)
PR preview


https://github.com/user-attachments/assets/7d90f384-6bee-41d7-9aec-cadb434e7db6



closes https://github.com/twentyhq/twenty/issues/10561
2025-05-12 14:13:59 +02:00
GuillimandGitHub e87c6236ca calendar sync failed (#11970)
# TLDR 
fix bug due to some event properties coming from the google calendar API
containing weird characters like this
"\u0000�4\u000b\u00042��K\u0001�z,\u001cm�",

it made the Postgres select and insert operator fail



## Details
We can have event properties (like cal UID below) encoded in a strange
way. From my research, the character \u0000 comes from `C` language to
signal end of line. It is wrongly interpreted by Postgres so must be
escaped. I decided to remove all possibility of failure with this regex
`[^\x20-\x7E]` basically "any character that is not a printable ASCII
character"

```
[
  "5foijj28qb8smqiafjablo17vd@google.com",
  "\u0011�\"�f�\\\u0019G_=��\u0005]x",
  "?}|��\f}l��+�弴�",
  "%���?t\u0007��n\u001e\u000eY�T<",
  ".\u0011�\u0016�!�\u000eIǹ� ��\u001f",
  "!h\u0004��D�6���h�]E",
  "(�CX]�Q�7�^��n\u0006�",
  "_040000008200E00074C5B7101A82E0080000000070105B958DEFD801000000000000000010000000EA30DB22E888B943A8EE0AD483F8DB35",
  "\t�N�#�D��Ic�h",
  "+�)�H���jJ|Ժ�'�",
  "_040000008200E00074C5B7101A82E0080000000070A54736C6EED8010000000000000000100000006502334AFE61904595C2831FA4391034",
  "_040000008200E00074C5B7101A82E0080000000072C80C3590EFD8010000000000000000100000001BA9FD5B330C1A4D85462AC9D70B9D9D",
  "sg�fvUa:St>-<�d\u0006",
  "\u0017ڦ��_\u001e\u001fGm-1����",
  "_040000008200E00074C5B7101A82E00800000000F0F4F01F4EF0D8010000000000000000100000004C11CE0950C85549B79C456C13987AB8",
  "$�����\u0007V\u0007��\u001e�OLN",
  "_040000008200E00074C5B7101A82E00800000000341DA81151EDD8010000000000000000100000007453CEFB19AA2D4899B17F0BDB000493",
  "_01C756CA-98DC-4799-9F06-883A540A065C",
  "_040000008200E00074C5B7101A82E00800000000919548BBF1EDD80100000000000000001000000050AE1E41F3CD314CA9215F193EBE1D39",
  "_040000008200E00074C5B7101A82E0080000000039CF64D718EDD801000000000000000010000000B3824EF0711436488CB5459BE83733B1",
  "_040000008200E00074C5B7101A82E00800000000C50BDADCB5E4D8010000000000000000100000005B95FE762B2EF84B9C5AC53907B7E5E8",
  "�Spx�\u0003ve��ss�X��",
  "\b���>\u0013̈�ыh��0�",
  "_040000008200E00074C5B7101A82E008000000005BCD492230E8D801000000000000000010000000B243A9CE99E94C4DAD201129A8F2A2F7",
  "_040000008200E00074C5B7101A82E008000000009B540B82D1DCD801000000000000000010000000B4AFC9825D94994AA6C528C953BD3D96",
  "_040000008200E00074C5B7101A82E008000000000D39EABDB7E4D801000000000000000010000000CD07BA2D05E61B47A597EE538ECE8CA5",
  "\u0016���\u0003inv�=O����",
  "4?b�-���\u001c\u0013ת�E�p",
  ">\u0000\u0015-;_�^�W&�p\u001f�",
  "_040000008200E00074C5B7101A82E008000000006258818C85D9D80100000000000000001000000003346C625768FE43AF3F8D09917CA3C9",
  "+K��ٔ�\u0006�\u0018G\u000b\u0000�s\u000e",
  "/\f�\rj�IOD�g脅��",
  "_68d820f9-e2c1-4d9a-bf61-83e4957c8261",
  "xĠ�W4>���t�\u001d���",
  "_040000008200E00074C5B7101A82E008000000003F1F314328E3D8010000000000000000100000002C8DC60F5369F44DA2B066441F882B35",
  "_040000008200E00074C5B7101A82E008000000006DFCC204FDDED80100000000000000001000000046ECD444737D2E4992C349B2EA05637F",
  "_1FF7C1BB-4E1A-485F-ADD0-5C4768601179",
  "_040000008200E00074C5B7101A82E00800000000A0AA1223EFD3D801000000000000000010000000C83B72C2B424944199F3353D1442B27E",
  "_040000008200E00074C5B7101A82E0080000000063D101EB06E4D801000000000000000010000000E489F61C89B8914BA6F8C8A2606405FE",
  "\u0011��f�\"�b���rB�[�",
  ";t��\u001d\u001euDY+T\u001d��v",
]
```



Fixes https://github.com/twentyhq/core-team-issues/issues/946

Fixes
https://twenty-v7.sentry.io/issues/6568530279/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D%20b09d7a84-e6bc-45cf-b3ca-1e6047dddeed&referrer=issue-stream&stream_index=0


### Edit :
Changed the regex to match the chars to remove from 
`[^\x20-\x7E]` to `replace('\u0000', '');`
2025-05-12 14:09:57 +02:00
Baptiste DevessierandGitHub a4656b415c Improve Form Layout + add drag and drop (#11901)
https://github.com/user-attachments/assets/cf542921-9354-4f7b-b6e8-061ebcaa9a9b

Closes https://github.com/twentyhq/core-team-issues/issues/887
Closes https://github.com/twentyhq/core-team-issues/issues/889
Closes https://github.com/twentyhq/core-team-issues/issues/890
2025-05-12 12:09:46 +02:00
EtienneandGitHub ca6e979ead fixes on search (#11955)
In this PR
- enable search by email
- search with ' ' (spaces) string and special characters do not throw
entry error

closes https://github.com/twentyhq/twenty/issues/11447 &
https://github.com/twentyhq/core-team-issues/issues/860
2025-05-12 08:59:10 +00:00
martmullandGitHub 650f8f5963 Revert "Revert "[4/n]: migrate the RESTAPI GET /rest/* to use TwentyORM direc…" (#11349) 2025-05-12 08:32:04 +00:00
1f4d4c5265 fix: z-index conflict between aggregate footer and cell popups (#11973)
https://github.com/user-attachments/assets/06f0e76f-69df-4a34-90ca-8d177744d89b

Closes #11956

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-11 12:24:49 +00:00
8216800a4a Fix workspace relation sync (#11963)
## Context

While deploying the IS_NEW_RELATION_ENABLED (we don't compute relation
based on relationMetadata anymore) to existing workspace, I've tested to
run a sync-metadata post feature flag activation. This has raised two
issues:
- the workspaceMigration generator (which is over-complex and should be
refactored later) for fieldMetadata of type RELATION was not handling
settings update properly ;
- we need to delete existing fieldMetadata corresponding to the UUID
foreignKey as they are not needed anymore. This is handled as a 0.53
upgrade command as 0.53 will also come with the full removal of the old
relation system

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: prastoin <paul@twenty.com>
2025-05-09 19:03:39 +02:00
Lucas BordeauandGitHub 3308ba56b2 Implemented ACTOR sub-field filtering (#11957)
This PR implements what's missing for ACTOR sub-field filtering,
filtering on the source sub-field was already working.

We can now filter on name sub-field. 

Since the sub-fields are different types and cannot be filtered both by
text, we consider that a simple filter on ACTOR is filtering on the
source, we have to go to advanced filter to have the name filter
sub-field.
2025-05-09 15:49:04 +00:00
EtienneandGitHub 1c0650fbd3 invert load more and add new (#11962)
closes https://github.com/twentyhq/core-team-issues/issues/847
2025-05-09 13:59:51 +00:00
Lucas BordeauandGitHub 8e07160c84 Implemented PHONES sub-field filtering (#11953)
This PR implements sub-field filtering for the PHONES field type.

What was tricky was to have filtering work correctly on the
additionalPhones sub-field, which is an array of objects and is treated
as a RawJsonFilter. Now that it works for this sub-field, we can
implement the same logic for other similar sub-field like
additionalEmails and secondaryLinks.
2025-05-09 14:32:57 +02:00
d63e53943e i18n - translations (#11950)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-09 11:46:15 +02:00
Lucas BordeauandGitHub afea017c12 Sub-field filtering on ADDRESS type (#11912)
This PR adds what's needed to filter on the ADDRESS sub-fields, notably
the country sub-field, that requires a country multi select component,
which was created in this PR (ObjectFilterDropdownCountrySelect)

This PR refactors the common logic between advanced filter dropdown
field selection logic and view bar filter dropdown field selection
logic, notably in useFilterDropdownSelectableFieldMetadataItems.

There are now new components to identify clearly what's tied to view bar
or advanced filter, it could be further simplified or factorized, but as
it is right now, it's simple enough to be maintained easily even if a
little bit too verbose, which is often the best trade-off we should aim
for.

Improvements : 
- Added the CompositeFieldSubFieldName where needed
- Fixes bug in advanced filter dropdown input
- Fixes dropdown content width bug in advanced filter dropdown input
- Fixes a bug when inputing a Currency filter without a sub-field in
view bar filter dropdown
- Used DropdownMenuSearchInput instead of a custom StyledInput which was
doing exactly the same thing
- Factorized the state setting logic in
useSetAdvancedFilterDropdownStates in an anonymous function
setAdvancedFilterDropdownStates
- Created useSelectFilterFromViewBarFilterDropdown hook to have a more
meaningful and clear logic to abstract what happens when we select a
field to filter in the view bard field select dropdown
- Fixes a bug with advanced filter operand dropdown select which wasn't
modifying the current record filter and creating a stale state.

Fixes https://github.com/twentyhq/core-team-issues/issues/612
2025-05-09 09:32:46 +00:00
Paul RastoinandGitHub 97d44d13ba Fix field currency form settings (#11948)
# Introduction
Close #11947 

From my understanding this `singleQuote` manipulation is legacy due to
front preparing sql queries in some way.

We might wanna standardize this behavior for each `CURRENCIES` usage,
such as within the `ObjectFilterDropdownCurrencySelect` that does not
send nor expect singled quoted encapsulated currencies values.

Created core-team-issues tech issue
https://github.com/twentyhq/core-team-issues/issues/941


## Field creation variables
```json
{
  "input": {
    "field": {
      "defaultValue": {
        "amountMicros": null,
        "currencyCode": "'BYN'"
      },
      "description": "",
      "icon": "IconMoneybag",
      "label": "Maquito",
      "name": "maquito",
      "isLabelSyncedWithName": true,
      "objectMetadataId": "6ef5da20-cf03-49b5-81fe-73aa2c9856a9",
      "type": "CURRENCY"
    }
  }
}
```

## Filtering variables
```json
{
  "filter": {
    "test": {
      "currencyCode": {
        "in": [
          "ALL",
          "AED",
          "AFN",
          "ANG"
        ]
      }
    }
  },
  "orderBy": [
    {
      "position": "AscNullsFirst"
    }
  ]
}
```
2025-05-09 10:57:59 +02:00
Yadong (Adam) ZhangandGitHub 3e9bff22bb fix(ui): added primary blue accent disabled color. (#11945)
Close #11941 

<img width="992" alt="Screenshot 2025-05-08 at 23 23 14"
src="https://github.com/user-attachments/assets/99017653-5a49-4025-983b-04ef8b3fcdcd"
/>
2025-05-09 08:50:45 +02:00
Abdul RahmanandGitHub ff4db92900 fix: flickering when updating relation counts (#11943)
https://github.com/user-attachments/assets/f5a87f1d-7c9f-4351-b43a-8b9b47715f94

Closes #11853
2025-05-09 08:28:20 +02:00
Abdul RahmanandGitHub 1a761e39a9 Fix record name column overlapping table footer on horizontal scroll (#11937)
https://github.com/user-attachments/assets/0a119cc4-2085-4cec-967e-61827f938f24



Closes #11889
2025-05-08 15:16:22 +02:00
Félix MalfaitandGitHub 51f7f55b9d Fix condition for preview apps (#11933)
Followup after https://github.com/twentyhq/twenty/pull/11869

We do want to launch previews on every PR. The label is just there to
force a re-launch
2025-05-07 21:27:53 +02:00
c4482f6be6 fix: avoid passing invalid to prop to DOM (#11931)
Fixed a React warning caused by the to prop being passed to the DOM when
its value was undefined or false. Since to is not a valid HTML
attribute, this triggered a console error. The prop is only used for
styling logic, so I used Emotion’s shouldForwardProp to prevent it from
being passed to the DOM, resolving the issue cleanly.

![Screenshot 2025-05-07 at 10 00
54 PM](https://github.com/user-attachments/assets/0660af7f-df98-46a3-b9f2-2ccc993ac227)

#11850

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-05-07 21:12:15 +02:00
Bhavik AgarwalandGitHub e5888d11e2 Note link's color contrast fixed in dark mode (#11932)
# Note link's color contrast fixed in dark mode

## Key changes

This pull request introduces a minor styling update to the `BlockEditor`
component in `BlockEditor.tsx`. It adds a new style rule to ensure
inline links within the `.bn-inline-content` class are styled with the
theme's blue color.

### Styling updates:

*
[`packages/twenty-front/src/modules/ui/input/editor/components/BlockEditor.tsx`](diffhunk://#diff-4a66ce7d5588bddc6237ac1a3b2949fe4432182bd357114294e8a79d98afce51R119-R122):
Added a CSS rule to style links (`<a>` elements) within
`.bn-inline-content` to use the theme's blue color.

## Issue
fixes #11917 


![image](https://github.com/user-attachments/assets/15a15aa4-be46-4d66-9cfa-55b5d961a6ca)
2025-05-07 21:04:01 +02:00
Félix MalfaitandGitHub 7a4599321b Prepare for schema fusion (#11922)
## Architecture Detail

The goal is to merge the two TypeORM schemas.
Having two schemas prevent doing things like fieldMetadata.workspace in
TypeORM, and create useless debates since there is no clear line (is a
serverlessFunction core or metadata? What about events? etc.)

### Before
```
┌───────────────────┐    ┌───────────────────┐
│  core schema      │    │  metadata schema  │
├───────────────────┤    ├───────────────────┤
│- User             │    │- ObjectMetadata   │
│- Workspace        │    │- FieldMetadata    │
│- UserWorkspace    │    │- RelationMetadata │
│- etc.             │    │- etc.             │
└───────────────────┘    └───────────────────┘
```

### After the Migration
```
┌───────────────────────────────────────────┐
│              engine schema                │
├───────────────────────────────────────────┤
│- User                - ObjectMetadata     │
│- Workspace           - FieldMetadata      │
│- UserWorkspace       - RelationMetadata   │
│- etc.                - etc.               │
└───────────────────────────────────────────┘
```

## Strategy

1. During 0.53 we backfill the *_typeorm_migrations* table of the core
schema with all metadata migrations
2. That way in 0.54 we can move the metadata migrations from the
metadata folder to the core folder. We will also edit the migration
files to reference "core" instead of "metadata". For people doing a
fresh install this will run smoothly and create the tables in Core
directly. For people on an existing install, this migrations will not
run because they were added to the *_typeorm_migrations* in 0.53
3. In 0.55 we will rename "core" to something else (for example
"engine")

Note: if someone jumps version, for example skips to 0.54 directly
without having run 0.53 then this could cause issue. In 0.54 we should
consider gating the "migrate:prod" in the docker file so that it's
controlled and run by the upgrade command (and not run if the command
wasn't executed properly)
2025-05-07 15:13:47 +00:00
WeikoandGitHub 09850c827f Fix codegen and missing track mutation (#11928)
Track mutation was recently renamed TrackAnalytics which broke
apollo.factory.test.ts specs due to signature mismatch. This also broke
other surfaces depending on this such as codegen.
I've also ran codegen since it was a bit outdated
2025-05-07 17:11:00 +02:00
EtienneandGitHub 590aaa1fd4 fix on field relation preview (#11926)
To reproduce : 
Modify object destination to an object with a 'simple' field as
labelIdentifier from data model settings, during creation of a relation
field from an object which has a composite field as labelIdentifier +
Relation type 'has many'

Fix : 
fieldValue and fieldDefinition does not update at the same time (when
object destination is modified) in RelationToManyFieldDisplay component.
Need to better define recordId to be sure fieldValue doesn't point on
previous record.

Tested : 
Relation field creation from Person with switch on relationType and
objectDestination (company/workspaceMember)
Relation field creation from Company with switch on relationType and
objectDestination (pet/person)
closes https://github.com/twentyhq/twenty/issues/11826
2025-05-07 14:46:40 +00:00
Paul RastoinandGitHub a78f3f0d89 Fix duplicated workspace id in activeOrSuspendedCommandRunner options (#11903)
# Introduction
From my understand we're kinda hacking through the options parser by
defining class properties within them whereas we should be consuming the
return type value ? Have no time for this right now

Anw for some reason nestjs-commander enters several time the option
parse which result in duplicating the given workspaceId in the array

Added a Set to fix

close https://github.com/twentyhq/twenty/issues/11707
2025-05-07 14:45:16 +00:00
Paul RastoinandGitHub f129bc0ac4 Upgrade infer commands from APP_VERSION (#11881)
# Introduction
This PR refactors the way we previously manually handled the upgrade
command `versionTo` and `versionFrom` values to be replaced by a
programmatic inferring using the `APP_VERSION` env variable. It raises
new invariant edge cases that are covered by new tests and so on

Please keep in mind that an upgrade will run agnostically of any `patch`
semver value as it should be done only when releasing a `major/minor`
version update
[Related discord
thread](https://discord.com/channels/1130383047699738754/1368953221921505280)

## Testing in local
In order to test in local we have to define an `APP_VERSION` value in
`packages/twenty-server/.env` following semver ( or not 🙃 )

## Logs example
```ts
Computing new Datasource for cacheKey: 20202020-1c25-4d02-bf25-6aeccf7ea419-8 out of 0
query: SELECT * FROM current_schema()
query: SELECT version();
[Nest] 37872  - 05/06/2025, 4:07:21 PM     LOG [UpgradeCommand] Initialized upgrade context with:
   - currentVersion (migrating to): 0.53.0
   - fromWorkspaceVersion: 0.52.0
   - 2 commands
[Nest] 37872  - 05/06/2025, 4:07:21 PM     LOG [UpgradeCommand] Upgrading workspace 20202020-1c25-4d02-bf25-6aeccf7ea419 from=0.52.0 to=0.53.0 1/2
[Nest] 37872  - 05/06/2025, 4:07:21 PM     LOG [UpgradeCommand] Upgrade for workspace 20202020-1c25-4d02-bf25-6aeccf7ea419 ignored as is already at a higher version.
[Nest] 37872  - 05/06/2025, 4:07:21 PM     LOG [UpgradeCommand] Running command on workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db 2/2
Computing new Datasource for cacheKey: 3b8e6458-5fc1-4e63-8563-008ccddaa6db-8 out of 0
query: SELECT * FROM current_schema()
query: SELECT version();
[Nest] 37872  - 05/06/2025, 4:07:21 PM     LOG [UpgradeCommand] Upgrading workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db from=0.52.0 to=0.53.0 2/2
[Nest] 37872  - 05/06/2025, 4:07:21 PM     LOG [UpgradeCommand] Upgrade for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db ignored as is already at a higher version.
[Nest] 37872  - 05/06/2025, 4:07:21 PM     LOG [UpgradeCommand] Command completed!
```

## Misc
Related to https://github.com/twentyhq/twenty/issues/11780
2025-05-07 13:48:19 +00:00
Thomas TrompetteandGitHub e96afe444f Create filter action (#11904)
Figma
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=59956-288587&t=Dkp83eigIgb3DO6W-11

Issue
https://github.com/orgs/twentyhq/projects/1/views/3?filterQuery=sprint%3A%40current+assignee%3A%40me&pane=issue&itemId=108202682&issue=twentyhq%7Ccore-team-issues%7C897

- filters will be stored as existing GQL filters. It will avoid
re-building frontend
- `applyFilter` function will take the filter and a JS array in input
and returns the filtered array
- filter action calls the util then returns an empty result and error if
no data in the output array. It will end the workflow gracefully.

Example of action:

```
{
      "id": "9d4aeee9-5b78-4053-9615-c367e901ed71",
      "name": "Filter",
      "type": "FILTER",
      "valid": false,
      "settings": {
        "input": {
          "filter": {
            "employees": {
              "gt": 300,
            },
          }
        }
      }
}
```
2025-05-07 14:52:03 +02:00
MarieandGitHub 463dee3fe6 Remove usages of connectToDataSource and use workspaceDataSource (#11873)
In this PR we are

1. cleaning typeORM service by removing connectToDataSource method
2. using workspaceDataSource instead of mainDataSource when possible,
and replacing raw SQL with workspaceRepository methods to use
2025-05-07 10:42:51 +02:00
Abdul RahmanandGitHub b5bacbbd29 Disable Cell Hover Effect During Row Selection (#11908)
https://github.com/user-attachments/assets/925c02b7-6e34-4bb6-8f9e-2426de57088c



Closes #11878
2025-05-07 09:52:23 +02:00
Félix MalfaitandGitHub 7b78b64bca Update clickhouse tables (#11905)
Following a discussion with @Bonapara - changing the base tables
2025-05-07 09:39:18 +02:00
Cole RichardsonandGitHub 8b796647f9 small Update to what-is-twenty.mdx (#11909)
fixed some grammatical errors. self explanatory
2025-05-07 06:52:31 +02:00
fd8da3d943 i18n - translations (#11902)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-06 18:48:51 +02:00
Raphaël BosiandGitHub c726a7d524 Fix input width (#11897)
Fixes #11742. The bug introduced by
https://github.com/twentyhq/twenty/pull/11536
2025-05-06 18:43:53 +02:00
EtienneandGitHub a2388d2dc7 chunk csv file before preview (#11886)
closes https://github.com/twentyhq/twenty/issues/10971
2025-05-06 17:43:32 +02:00
Paul RastoinandGitHub f2691e53a0 [CI]: Increase status check timeout (#11896)
# Introduction
Some jobs start to fail because they exceed the timeout
Such as this job
https://github.com/twentyhq/twenty/actions/runs/14862320942/job/41730200276?pr=11881
2025-05-06 17:14:58 +02:00
Raphaël BosiandGitHub b3f5a3f75f Record Table Row Navigation (#11879)
# Record Table Row Navigation

This PR improves the table accessibility by adding a row navigation and
new shortcuts to the table. Closes #896.

# Introduce focused active row states on the table

This PR implements the focused and active row states feature for the
record table, allowing users to navigate through the table with keyboard
arrows and providing visual feedback for selection.

## Implementation details:

- Added new component states to track focused and active row positions
and states.

- Implemented dedicated hooks for row state management

- Updated UI styling for active and focused rows:
  - Applied blue border (Adaptive Colors Blue 3)
  - Added highlight background (Accent Quaternary)
  - Added styling for focused rows to clearly indicate selection state

- Added row state cleanup:
- `RecordTableDeactivateRecordTableRowEffect` component to reset states
  - Added row state reset logic upon navigation

## Bug fixes
- Fixed record table unselection in the page change effect
- Fixed a hack introduced by
https://github.com/twentyhq/twenty/pull/8489 which duplicated the last
table column

# Shortcuts

## Arrow keys and J+K navigation


https://github.com/user-attachments/assets/6b46f6b5-cd98-4053-aaef-f8bf2b9584b5


## Record selection with X


https://github.com/user-attachments/assets/44ab7397-e00c-4dfe-8dd1-b3ffc53b3e5f


## Enter allows for cell navigation, Escape goes back to row navigation


https://github.com/user-attachments/assets/890d7e25-2d81-47e3-972f-043a1879b8cc


## Command + Enter opens the record



https://github.com/user-attachments/assets/cf8cdbd5-7cf0-4d78-909f-dc6be88b9e25
2025-05-06 12:52:05 +00:00
f1d658bcb6 Fix: Twenty-website docs same TOC ids #11865 (#11872)
This PR fixes issue https://github.com/twentyhq/twenty/issues/11865.

The highlight heading logic in TOC was checking the heading text which
could be the same for multiple headings.
The ids for these headings were also just the heading texts, leading to
conflict in ids too.

Fix:
- Appended index of the heading item from the list of headings to the id
of the heading. This fixed conflicting ids.
- Used these unique ids to toggle the highlight style.

Behaviour after the fix:


https://github.com/user-attachments/assets/ab3bc205-0b0e-451d-b9cb-4fa852263efc


Edit:
close #11865

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-05-06 14:34:52 +02:00
Thomas TrompetteandGitHub 6810ca0204 Move workflow backfill command to 0.53 (#11892)
As title. It has not been added to 0.52 list of commands
2025-05-06 14:09:18 +02:00
2f85471955 i18n - translations (#11890)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-06 11:46:38 +02:00
ef8b015741 Allow moving columns left/right in Kanban view (#11827)
### Demo


https://github.com/user-attachments/assets/9bc81c33-454d-4581-b06e-dbc0ea79a8dd

Closes #11791

---------

Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-05-06 11:39:57 +02:00
GuillimandGitHub e92117d556 Critical email sync bug (#11885)
Removing the upsert to avoid the ON CONFLICT
2025-05-06 11:17:27 +02:00
Lucas BordeauandGitHub 9435d525cf Clean up record filter refactor (#11884)
This PR cleans up after the refactor of selected filter state and apply
filter logic on record filter.

Since everything is now using the new
objectFilterDropdownCurrentRecordFilter state to derive the value for
all types, we don't need to maintain states for selected record ids and
selected options and the ViewBarFilterEffect that was initializing them.

Details :
- Removed objectFilterDropdownSelectedRecordIdsComponentState
- Removed objectFilterDropdownSelectedOptionValuesComponentState
- Removed ViewBarFilterEffect
2025-05-06 10:28:20 +02:00
EtienneandGitHub a60711c808 Ej/fix message visibility (#11874)
<img width="257" alt="Screenshot 2025-05-05 at 15 30 09"
src="https://github.com/user-attachments/assets/5a8e18e0-efc5-4521-9c3a-bf73277ecdf9"
/>
<img width="257" alt="Screenshot 2025-05-05 at 15 29 05"
src="https://github.com/user-attachments/assets/c1a784af-a744-497a-b6ce-ec3a9e8b851a"
/>
<img width="257" alt="Screenshot 2025-05-05 at 15 33 06"
src="https://github.com/user-attachments/assets/c5fabd1d-a125-49d7-aade-0a208a0eff95"
/>

related to PR https://github.com/twentyhq/twenty/pull/11840 and issue
https://github.com/twentyhq/twenty/issues/9826
2025-05-05 17:23:27 +02:00
GuillimandGitHub da0c7e679e Blocknote editor fix (#11823)
After reading the blocknote documentation :

- we decided to increase to 100% the lines width
- we decided to reduce as much as possible inner padding
- we decided it's on the parent to decide the padding of the richtext
The two last points are recommended in a discussion on the project
blocknote. This way clicking on padding won't trigger weird behaviour on
Chrome.

Fixes
https://github.com/twentyhq/core-team-issues/issues/827#issuecomment-2842350359
2025-05-05 17:22:49 +02:00
MarieandGitHub a9e73c6340 [permissions] Add permissions check layer in entityManager (#11818)
First and main step of
https://github.com/twentyhq/core-team-issues/issues/747

We are implementing a permission check layer in our custom
WorkspaceEntityManager by overriding all the db-executing methods (this
PR only overrides some as a POC, the rest will be done in the next PR).
Our custom repositories call entity managers under the hood to interact
with the db so this solves the repositories case too.
This is still behind the feature flag IsPermissionsV2Enabled.

In the next PR
- finish overriding all the methods required in WorkspaceEntityManager
- add tests
2025-05-05 14:06:54 +00:00
5f8040af5d Modify Decimal Fields to be treated as number in OpenAPI schema. (#11871)
Closes https://github.com/twentyhq/twenty/issues/10807

## Description
This PR will Modify Decimal Fields to be treated as `number` in OpenAPI
schema.

## Testing
<img width="989" alt="スクリーンショット 2025-05-05 20 49 05"
src="https://github.com/user-attachments/assets/2f120317-5860-4c93-91a2-f521a69a1cd5"
/>
<img width="872" alt="スクリーンショット 2025-05-05 20 49 52"
src="https://github.com/user-attachments/assets/0d319785-e30b-4132-be9e-12ed6f3cc46a"
/>

---------

Co-authored-by: Takuya Kurimoto <takuya004869@gmail.com>
Co-authored-by: prastoin <paul@twenty.com>
2025-05-05 15:48:23 +02:00
Thomas TrompetteandGitHub 6128d660c2 Fix form record picker field (#11817)
- enrich response so the record is available in the step output. Today
this is available in the schema but only the id is set
- make the full record picker clickable instead of the arrow only

<img width="467" alt="Capture d’écran 2025-04-30 à 16 08 04"
src="https://github.com/user-attachments/assets/db74b9a6-7f1d-4e54-bf06-9be3d67ee398"
/>
2025-05-05 12:58:11 +00:00
Paul RastoinandGitHub c9eff401df Preview env dispatch using -paths syntax (#11869)
# Introduction
Using changed-files from a forked repo with `pull_request_target`
results in invalid checkout issue
Used the native paths GitHub Actions syntax to handle workflow
triggering

[Paths
syntax](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore)
2025-05-05 14:30:16 +02:00
e5bfca2b1d Fix crash when hiding a column in Kanban view (#11847)
### Problem
When hiding a kanban view column, users encountered the following error:
`Instance id is not provided and cannot be found in context.`

This was caused by the `SelectableListItem` for the "HiddenGroups" menu
item not being wrapped in a `SelectableList`. As a result, the required
context (specifically, the selectableListInstanceId) was missing,
leading to errors in recoil state management.

### Solution
This PR wraps the "HiddenGroups" `SelectableListItem` in its own
`SelectableList` component, providing the necessary context and ensuring
that the component family selectors work as expected.


https://github.com/user-attachments/assets/19e030d0-a28a-4993-b952-99d10b6e7a92

Closes #11828

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-05-05 13:46:00 +02:00
EtienneandGitHub 521e75981a Fix calendar events & messages fetching + fix timeline design (#11840)
Preview : 

<img width="501" alt="Screenshot 2025-05-02 at 16 24 34"
src="https://github.com/user-attachments/assets/0c649df1-0e26-4ddc-8e13-ebd78af7ec09"
/>


Done : 
- Fix getCalendarEventsFromPersonIds and getCalendarEventsFromCompanyId
(include accountOwner check)
- Fix permission check on pre-hook - Pre-hook seems useless, calendar
events are always on METADATA or SHARE_EVERYTHING visibility, else post
hook always has the responsibility of returning the data user can
access. >> To delete or to keep in case other visibility options are
added ?
- Add post hook to secure finOne / findMany calendarEvents resolver
- Update design

To do :
- same on messages (PR to arrive)

closes : https://github.com/twentyhq/twenty/issues/9826
2025-05-05 13:12:16 +02:00
Paul RastoinandGitHub d0d872fdd0 Upgrade guide fix docs (#11867)
# Introduction
Related to https://github.com/twentyhq/twenty/pull/11834
2025-05-05 13:11:10 +02:00
Baptiste DevessierandGitHub 1543c900ae Migrate workflow states to component states (#11773)
- Migrated all workflow Recoil states to component states to isolate
each workflow visualizer instance. The use case of having two workflow
visualizers displayed at the same time appeared recently and will grow
in the near future.
- We chose to use the `recordId` as the value for the `instanceId` of
the component states. Currently, there are a few cases where two
workflows or two workflow runs are rendered at the same time. As a
consequence, relying on the `recordId` is enough for the moment.
- However, there is one case where it's necessary to have a component
state scoped to a workflow visualizer instance: the
`workflowVisualizerStatusState`. This component is tightly coupled to
the `<Reactflow />` component instance rendered in the workflow
visualizer, and it must be set to its default value when the component
first renders. I achieved that by using another component instance
context whose instanceId is an identifier returned by the `useId()` hook
in the Workflow Run Card component.
2025-05-05 10:58:11 +02:00
8b68dce795 i18n - translations (#11863)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-05 10:37:51 +02:00
ee1fe3564a fix: Restoring record results in blank line in TimelineActivity (#11679) (#11856)
Fixes issue #11679 
There were no case of restored so it was defaulting to null thus showing
the blank line

Handled case for restored so it doesn't default to null 

Image shows record restored by the user and restored by other user
![Screenshot 2025-05-03
011257](https://github.com/user-attachments/assets/8b848992-4250-4266-9a3e-1ca89e1a06b8)

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-05-05 10:25:12 +02:00
a570be0ad1 i18n - translations (#11861)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-05-04 14:42:30 +02:00
Félix MalfaitGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
49b7f5255f Update what is being audit logged (#11833)
No need to audit log workflow runs as it's already a form of audit log.
Add more audit log for other objects
Rename MessagingTelemetry to MessagingMonitoring
Merge Analytics and Audit in one (Audit)

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-05-04 14:35:41 +02:00
Matt DrolletteandGitHub b1994f3707 Use correct env var name in podman-compose (#11858)
The example .env file uses `PG_DATABASE_PASSWORD` so this makes it
consistent. Currently, the podman-compose directions will fail on first
run unless you manually change the env var name.
2025-05-04 12:23:02 +02:00
EtienneandGitHub 9d5f4bf8fd fix relation creation bug (#11848)
Context : In `RelationToOneFieldDisplay`, the `objectNameSingular` used
for the chip calculation was incorrect - it was using the value from the
opposite side of the relationship. Then, labelIdentifier based on
composite fields were causing errors (People and WorkspaceMembers with
name)


<img width="300" alt="Screenshot 2025-05-03 at 08 03 46"
src="https://github.com/user-attachments/assets/8d034700-5244-4b1b-978e-f77ae78b6ceb"
/>


Tested everywhere FieldDisplay is used. 
Tested for each both relation type. 

closes https://github.com/twentyhq/twenty/issues/11826
2025-05-03 06:21:33 +00:00
Paul RastoinandGitHub ea0f45e782 Scope permissions to dispatch reusable workflow invokation (#11843)
# Introduction

Fixes `preview-dispatch` for external contributors such as this run 
FAILING =
https://github.com/twentyhq/twenty/actions/runs/14796579485/job/41545030774
NOW SUCCEEDING =
https://github.com/twentyhq/twenty/actions/runs/14797811684?pr=11827
2025-05-02 17:32:49 +02:00
Lucas BordeauandGitHub 5946b37712 Refactored object filter dropdown input state management (#11838)
This PR refactors the generic module object dropdown filter input.

We have multiple components for each filter type and each one was using
selectedFilterState and the applyRecordFilter hook to read and set its
value.

The main issue was that each component was forced to pass every property
of a RecordFilter to applyRecordFilter to only modify the value
property, thus creating a lot of unnecessary dependencies and tight
coupling between every component and hook that used the record filters.

Now we have each component only reading from a new
objectFilterDropdownCurrentRecordFilterComponentState, scoped to a
ObjectFilterDropdownComponentInstanceContext, thus whether we're in a
view bar dropdown, an editable filter chip dropdown or an advanced
filter dropdown, we know where to read the filter value from.

This component state might even be simplified by only storing the record
filter id, thus avoiding having to synchronize this state with its
counterpart in currentRecordFilterComponentState, but we should try
after the main refactor effort, as those two states aren't in the same
instance context.

We implement a new applyObjectFilterDropdownFilterValue hook to handle
the value setting from an object filter dropdown input component.
There's also a new useApplyObjectFilterDropdownOperand for doing the
same but for operand.

Another important thing that had to be done to keep a synchronous code
path was to set the states of each advanced filter row at the advanced
filter dropdown onOpen event, using useSetAdvancedFilterDropdownStates.

Finally we remove : useApplyRecordFilter, useSelectFilterUsedInDropdown
and selectedFilterComponentState which were making all of this zone
difficult to work with.

Closes https://github.com/twentyhq/core-team-issues/issues/718
Closes https://github.com/twentyhq/core-team-issues/issues/720
2025-05-02 17:28:45 +02:00
Abdul RahmanandGitHub aa2b27dcbe Fix unwanted right padding in Options view menu (#11841)
<img width="235" alt="Screenshot 2025-05-02 at 7 46 04 PM"
src="https://github.com/user-attachments/assets/94275278-ff14-44fd-a09a-776755ad1fa8"
/>

Closes #11839
2025-05-02 16:51:15 +02:00
Paul RastoinandGitHub abc05fafd7 Redis max memory limit and eviction policy (#11836)
# Introduction
Redis [eviction
policy](https://redis.io/docs/latest/operate/rs/databases/memory-performance/eviction-policy/)
and [Key
eviction](https://redis.io/docs/latest/develop/reference/eviction/)
[Bullmq eviction
recommendations](https://docs.bullmq.io/guide/going-to-production#max-memory-policy)


We might need a dedicated bullmq redis instance, as sharing
engine/metadata keys and bull will someday become problematic

close https://github.com/twentyhq/core-team-issues/issues/452

About to open a PR for our internal IaC

Ps: Did not set a `--maxmemory` that could be leading to undetermined
OOOM errors at runtime. Should be user provided or should define a
default value ?
2025-05-02 16:40:56 +02:00
Gitesh SarvaiyaandGitHub 48011ac012 fix: do not report EmailNotVerifiedError to Sentry (#11753) (#11835)
This PR prevents EmailNotVerifiedError from being reported to Sentry, as
discussed in issue #11753.

edit:
close #11753
2025-05-02 15:35:05 +02:00
Paul RastoinandGitHub 9a504606b8 Migrate/upgrade every time dockerfile entrypoint.sh (#11834)
# Introduction
`upgrade` and `migrate` are not run every time even, but only once on
database creation, tho we're suggesting users they do as not requiring
manual run anymore since `0.50`

close https://github.com/twentyhq/twenty/issues/11671
2025-05-02 14:35:45 +02:00
Paul RastoinandGitHub 3e1b4ace37 Standardize isDefined usage for metadata version assertions (#11829)
# Introduction
`!value` is risky as `!falsy` would return `true`
2025-05-02 11:07:12 +02:00
9df4778954 Fix: Reset password flow fails when user is signed in (#11811)
### Demo


https://github.com/user-attachments/assets/9589c7cc-f6ba-484a-b002-615c11a92729

Note: For the demo video, I hardcoded the email and manually set the
isTokenValid state to true.

Closes #11689

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: prastoin <paul@twenty.com>
2025-05-02 10:04:44 +02:00
Félix MalfaitandGitHub 8c3a2d8640 Verify seed users and change AppleCar password (#11825)
isEmailVerified was set to false which was annoying in the staging
environment

Also updated password for tim@apple.dev from AppleCar2025 to just
tim@apple.dev since the joke is outdated
2025-04-30 16:59:13 +00:00
Paul RastoinandGitHub 17334f8800 Fix undefined read attempt (#11816)
# Introduction
Followup of https://github.com/twentyhq/twenty/pull/11784
Again some propaganda for the
[noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig/#noUncheckedIndexedAccess)
that involved this @charlesBochet 👀
That's very risky to have this setup to false especially in the backend
regarding the twenty-server metadata nature

Also suggested that we do some integration testing ( e2e nestsJs tests )
on a related endpoint that could related we always retrieve the same
form result output

We could also do some unit testing of the method but like the idea to
ship it through the api itself
2025-04-30 17:58:27 +02:00
EtienneandGitHub c657caf74f force cache refresh for views after new object creation (#11806)
**Context** 
When creating a new object, it creates the "All ...." view associated.
After new object is created, in `PrefetchRunViewQueryEffect`,
findManyViews returns cached results WITHOUT the new view.

git bisect - regression introduced with
https://github.com/twentyhq/twenty/pull/10272

**Attempt** : Update to 'network-only' fetch policy in
`PrefetchRunViewQueryEffect` -> not working on useQuery apollo hook (🤯)
: query is handle by cache and not network

**Solution** 
Based on pattern used for view creation
(`useCreateViewFromCurrentView`), refreshing the view cache with a
`useLazyFindManyRecords` solves the issue. Then, `prefetchViewsState` is
updated in `PrefetchRunViewQueryEffect`


closes : https://github.com/twentyhq/core-team-issues/issues/845
2025-04-30 17:54:48 +02:00
EtienneandGitHub 6b9128d1ae fix rich text focus (#11821)
Before 


https://github.com/user-attachments/assets/419227fb-fc0e-4d6e-b89a-932b4b76666f

After


https://github.com/user-attachments/assets/e4db323c-2f98-46f6-84e7-8b9bb452e900


Tested in command Menu + table cell edit mode + "plain text" command
menu
2025-04-30 17:28:12 +02:00
4ce7834f94 i18n - translations (#11822)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-30 17:20:54 +02:00
martmullandGitHub 849a35955a 866 refactor cron trigger only one cron each minutes triggers all cron triggers (#11809)
<img width="1123" alt="image"
src="https://github.com/user-attachments/assets/75447922-81dd-4cfc-805d-f511f73cc778"
/>
2025-04-30 17:08:47 +02:00
GuillimandGitHub 357649db95 fix-discord-timeline (#11784)
In some cases, the person is undefined so we fallback on the
workspacemember, and sometimes he is missing the firstname/lastname.

Not sure how this can happen, but one user experiencd such a thing so
better to catch this


![image](https://github.com/user-attachments/assets/c91445fe-365e-4fc9-bf14-69f71d344aa7)

fix https://discord.com/channels/1130383047699738754/1366145144838951022

close https://github.com/twentyhq/core-team-issues/issues/918
2025-04-30 15:11:00 +02:00
Lucas BordeauandGitHub 0439b96eca Implement new parallel code path for object filter dropdown current record filter (#11807)
This PR implements a new clean parallel code path for handling the
filter manipulated in an object filter dropdown.

Remember that the object filter dropdown module is the generic, shared
module, that must be vertically implemented in those places : view bar
filter button, record table column header cell, view bar details filter
chip.

So here we implement, just for the text filter input (for example a
FULL_NAME field type), a new parallel code path logic, that runs on a
new state : objectFilterDropdownCurrentRecordFilterState

We still update the selectedFilter state, that is very close to the new
objectFilterDropdownCurrentRecordFilterState, but in order to be
cautious, and allow us to refactor incrementally, we implement a new
parallel code path and let the rest run on selectedFilterState for now.

The new way of working with the filter in the object filter dropdown,
includes smaller and more specific hooks :
- useApplyObjectFilterDropdownFilterValue instead of applyRecordFilter
which API generates a lot of tech debt
- useObjectFilterDropdownFilterValue to get the current value (might be
later removed if too thin)
- useUpsertObjectFilterDropdownCurrentFilter, to abstract a bit some
duplicated logic in useApplyObjectFilterDropdownFilterValue
- useCreateRecordFilterFromObjectFilterDropdownCurrentStates which
differs from the existing
useCreateEmptyRecordFilterFromFieldMetadataItem in that it uses the
current states instead of creating an empty filter with default values.
Those two logics are still very confusing and duplicated everywhere,
creating specific hooks makes it clear now.

This PR shouldn't cause any change in the behavior of the filtering
feature.

Fixes https://github.com/twentyhq/core-team-issues/issues/717
2025-04-30 14:55:37 +02:00
Félix MalfaitGitHubCopilotgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
cb513bc7a8 Set default locale according to browser locale (#11805)
We didn't get much complaints on Localization so I guess we can expand
it more and make it the default behavior to use the browser's locale
when you signup

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-30 13:11:40 +02:00
Félix MalfaitandGitHub e55ff5ac4a Change workflow dispatch permissions (#11812)
It seems that content: write is needed so that external contributors can
dispatch workflows
2025-04-30 13:06:57 +02:00
Félix MalfaitandGitHub 6343eaeb4f Change workflow preview env to pull_request_target (#11810)
It didn't work with external contributors
2025-04-30 12:31:56 +02:00
Abdul RahmanandGitHub 36ddf48ef0 Fix ⌘A selecting records instead of input text when creating a new view (#11783)
### Demo

https://github.com/user-attachments/assets/772e5b45-f55d-4d5f-9256-5a325b027d5d

Closes #11677
2025-04-30 09:40:25 +02:00
ea25498625 Fix dragging behavior below the last card when dragging below the new CTA button (#11781)
- Fixed an issue where dragging an item below the last card didn't work
when the card was dragged below the new CTA button (`destination.index
=== items.length` case).
- Moved the "new record" button outside of the draggable list

### Demo

https://github.com/user-attachments/assets/370f2c1f-4bb2-403b-b8ed-4afda064c98d

Closes #10197

---------

Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-30 09:34:56 +02:00
e6c1b70d9c i18n - translations (#11801)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-30 09:20:32 +02:00
e957b1acd6 Twenty config admin panel integration (#11755)
closes https://github.com/twentyhq/core-team-issues/issues/761
closes https://github.com/twentyhq/core-team-issues/issues/762

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-30 09:12:59 +02:00
842367f7bb i18n - translations (#11800)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-29 18:48:53 +02:00
69f92a697b i18n - translations (#11799)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-29 18:37:01 +02:00
2367ffd452 i18n - translations (#11798)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-29 18:21:20 +02:00
Thomas des FrancsGitHubFélix Malfaitgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
df95ce9ed8 Updated several emails template styles (#11797)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-29 18:08:45 +02:00
Lucas BordeauandGitHub d52cb26599 Refactored ObjectFilterDropdown into ViewBarFilterDropdown (#11794)
This PR refactors the non-generic part around ObjectFilterDropdown which
has been left in statu quo for months.

It also removes unused components. 

Overall this PR is doing renaming and it re-organizes files into their
relevant modules.

This clarifies a lot what's at the intersection between
object-filter-dropdown and views modules.

This PR was originally about removing any remaining useEffect around
ObjectFilterDropdown but there wasn't any.

## Details

### Removed unused files

- GenericEntityFilterChip
- SingleEntityObjectFilterDropdownButton (was used for the Task/Note
standalone page which doesn't exist anymore)

### Re-organized non-generic components into ViewBarFilterDropdown

- Use VIEW_BAR_FILTER_DROPDOWN_ID instead of OBJECT_FILTER_DROPDOWN_ID
- Use FILTER_FIELD_LIST_ID for selectable list
- Refactored ObjectFilterDropdownButton into a simple
ViewBarFilterDropdown
- Renamed MultipleFiltersDropdownContent to ViewBarFilterDropdownContent
- Renamed MultipleFiltersButton to ViewBarFilterButton
- Integrated MultipleFiltersDropdownButton to ViewBarFilterDropdown
- Renamed AdvancedFilterButton to ViewBarDetailsAddFilterButton

### Tests 

Fixed storybook test for ViewBarFilterDrodpown
2025-04-29 18:05:12 +02:00
Thomas TrompetteandGitHub d8b2e1fb34 Start using next step ids (#11683)
- update workflow executor
- update next step ids on step creation/deletion
- use these in workflow run
- use these in variables
2025-04-29 16:29:25 +02:00
Baptiste DevessierandGitHub 19f46a0091 Fix e2e tests (#11792) 2025-04-29 15:51:59 +02:00
Thomas TrompetteandGitHub fef627b7c2 Fix output schema type not defined (#11788)
Fixes https://github.com/twentyhq/twenty/issues/11778
2025-04-29 11:29:11 +00:00
MarieandGitHub 2482271545 Fix filter with empty field (#11787)
Attempt to fix https://github.com/twentyhq/core-team-issues/issues/899

Could not reproduce but that's the only place in the code where I found
that we build filters as such, with values for "in" being equal to
select options and not recordIds, as it seems to be the case from the
sentries (ex:
<img width="174" alt="Capture d’écran 2025-04-29 à 11 13 56"
src="https://github.com/user-attachments/assets/a0b62de1-fe23-4394-9f86-a205ee32b56c"
/>
)
2025-04-29 09:56:14 +00:00
Lucas BordeauandGitHub fda793ced2 Fix formatDateString test (#11786)
This PR fixes a broken test that makes the CI crash.

This is due to the library `date-fns` which now doesn't use the word
"about" in its relative date formatting, if we're not precisely on minus
2 months, which can change for example today the 29th of April, where
the 29th of February doesn't exist.

So instead of using months and falling into hard to test cases, we use
days instead, which is an easy and predictable relative computation.
2025-04-29 11:45:58 +02:00
GuillimandGitHub 4833ee2914 fix-default-picture-url (#11779)
Fixing the default avatar picture in /settings/profile
2025-04-29 10:30:05 +02:00
MarieandGitHub 23d71915f6 Improve metadata version caching (#11775)
Investigating https://github.com/twentyhq/core-team-issues/issues/756, I
found that the error actually stemmed from "Object metadata collection
not found" error.

While this is planned to be fixed by metadata performance improvements
(as stated in [sentry-boss
doc](https://docs.google.com/document/d/1ytbC5W6ZFUSJ3PoJ4IfKi2IehKZYw65mqCnc24aP4RM/edit?tab=t.0)
in "known issues"), I tried some easy improvements to reduce the number
of errors.
2025-04-29 09:53:19 +02:00
Raphaël BosiandGitHub 7be56862e4 Fix object metadata not found for id (#11777)
Fixes https://github.com/twentyhq/twenty/issues/11668

Fixed an error due to falling back to the main context store object
metadata when the one in the context store wasn't defined.

When closing the command menu, the
`contextStoreCurrentObjectMetadataItemIdComponentState` is reset, but
the ActionMenuContextProvider was falling back to the main context store
object metadata id, so the action components were mounted. But they
still tried to access the
`contextStoreCurrentObjectMetadataItemIdComponentState` which is
`undefined`, which lead to an error being thrown.

Fix:
- Removed the fallback to the main context store object metadata item
2025-04-28 18:18:15 +02:00
Lucas BordeauandGitHub 7563b8b919 Refactored editable filter chip dropdown opening (#11765)
This PR is refactoring a part of the ongoing filter refactor that was
blocking other refactor in that area.

Precisely, the dropdown filter that was used with the editable filter
chip was initialized by two conflicting useEffect, causing many unwanted
and hard to tackle bugs when modifying other places in the code that
used the same dropdown.

We also remove a difficult to maintain pattern around
onToggleColumnFilterComponentState, which was storing a click handler in
a state, we want to avoid this pattern.

The hook useHandleToggleColumnFilter is also removed and replaced by
useOpenRecordFilterChipFromTableHeader.

The code is now synchronous and starts from the user click event that is
triggered on a table cell header filter button click.

Also : 

- Created a useSetEditableFilterChipDropdownStates that allows to
separate the code path of filter chip dropdown from the code path of
view bar global filter dropdown (will be continued in another refactor)
- Added useCreateEmptyFilterFromFieldMetadataItem to abstract empty
filter creation when opening a filter dropdown (will be used for other
refactor)
- Created a useOpenDropdownFromOutside hook that will also be used for
other refactor on filter
- Deleted EditableFilterDropdownButtonEffect
- Removed call to ViewBarFilterEffect (will be completely removed in
other refactors)
2025-04-28 17:36:48 +02:00
Raphaël BosiandGitHub 6cf44ef3c2 Fix open record in menu (#11772)
Fix open record in menu
2025-04-28 16:39:44 +02:00
Thomas TrompetteandGitHub b182a676d7 Fix next step ids backfill command (#11769)
Twenty prod DB has been exported for testing.

Main updates:
- do not process workflow runs with less than 2 steps. Nothing to do.
- update runs by batches of 500. Will avoid java heap space issue
- add more logs
2025-04-28 16:24:15 +02:00
MarieGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
0881e35d64 Throw error if attempting to open RecordPage without recordId (#11768)
Closes https://github.com/twentyhq/core-team-issues/issues/857

The issue was caused by the fact that the preview chip was accidentally
made clickable while not linked to any record id:
<img width="763" alt="Capture d’écran 2025-04-28 à 15 17 32"
src="https://github.com/user-attachments/assets/c1d9bf61-edcb-442f-a914-eccc627ee190"
/>
this was fixed by [this
PR](https://github.com/twentyhq/twenty/pull/11745) (@etiennejouan)

It was causing the side panel to open while the record id was empty,
while this recordId is used in query filters (as it should be to fetch
record data), leading the queries to fail.
Let's early return with an error instead as it does not make sense to
open the record page with an empty recordId.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-28 13:36:19 +00:00
EtienneandGitHub 2586d0ec4f fix workflow chips not clickable (#11767)
bug introduced in this PR https://github.com/twentyhq/twenty/pull/1174
2025-04-28 15:30:26 +02:00
14afa57699 i18n - translations (#11758)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-27 19:01:13 +02:00
Abdul RahmanandGitHub 902cef78a1 Add Logout Confirmation Popup When Changing Workspace Subdomain (#11756)
This PR implements a confirmation popup on the Domain settings page when
a user attempts to save a subdomain change.
- When the user saves the updated subdomain, a confirmation modal is
shown.
- The modal informs the user that changing the subdomain will log them
and all other users out.
- If the user confirms, the subdomain change proceeds as normal.
- If the user cancels, the update is aborted and no changes are made.

### Demo


https://github.com/user-attachments/assets/dcea51c8-ffd2-40ca-bc75-0c0228df5344


Related Issue
Closes #11741
2025-04-27 18:47:06 +02:00
a15b87649a Twenty config core implementation (#11595)
closes https://github.com/twentyhq/core-team-issues/issues/760

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-26 09:21:59 +02:00
Félix MalfaitandGitHub bb8fa02899 Remove server preconnect (#11752)
Fixes #11738
2025-04-26 08:23:28 +02:00
7752b8b06f i18n - translations (#11750)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-25 19:45:48 +02:00
Lucas BordeauandGitHub 50cb32d122 Implement sub-field filtering on CURRENCY field type (#11726)
This PR implements sub-field filtering on CURRENCY field type and
improves many related zones.

- Created a ObjectFilterDropdownCurrencySelect dropdown component for
filtering on multiple currencies
- Added currencyCode sub-field to CurrencyFilter type
- Created getDefaultSubFieldNameForCompositeFilterableFieldType to avoid
situation where we don't have any sub field name in sub field filtering
situations.
- Implemented filtering for currencyCode in
computeFilterRecordGqlOperationFilter
- Implemented CURRENCY type in getRecordFilterOperands
- Implemented isMatchingCurrencyFilter for using in
isRecordMatchingFilter for proper optimistic rendering
- Created turnCurrencyIntoSelectableItem to help
ObjectFilterDropdownCurrencySelect

Testing : 
- Added test for currency sub fields in getOperandsForFilterType
- Completely reworked isMatchingCurrencyFilter test

Improvements : 
- Created a unique CURRENCIES constant to avoid re-creating it at
various places
- Derive the type FilterableFieldType from a constant array
FILTERABLE_FIELD_TYPES, so it's easier to work with
- Added areCompositeTypeSubFieldsFilterable
- Fixed a bug with empty value '[]' that was preventing the auto-removal
of a filter chip

Miscellaneous : 
- Created isExpectedSubFieldName util to do a type-safe check of a
subFieldName
- Better naming : renamed isCompositeField to isCompositeFieldType
- Created isCompositeTypeFilterableWithAny to specify which field types
are filterable by any sub field
- Better naming : renamed
ObjectFilterDropdownFilterSelectCompositeFieldSubMenu to
ObjectFilterDropdownSubFieldSelect
- Better naming : renamed ObjectFilterDropdownFilterSelect to
ObjectFilterDropdownFieldSelect
- Created isEmptinessOperand util instead of duplicating the same
hard-coded check in multiple places
- Better naming : used subFieldName instead of compositeFieldName for
consistency
- UseEffect removal : removed unnecessary useEffect in
MultipleSelectDropdown

Fixes a bug where Empty and Not weren't appearing in filter chip in
particular cases
Fixes https://github.com/twentyhq/core-team-issues/issues/498
Fixes https://github.com/twentyhq/twenty/issues/7558
2025-04-25 17:33:00 +00:00
f201091c68 512 Ability to navigate dropdown menus with keyboard (#11735)
# Ability to navigate dropdown menus with keyboard

The aim of this PR is to improve accessibility by allowing the user to
navigate inside the dropdown menus with the keyboard.
This PR refactors the `SelectableList` and `SelectableListItem`
components to move the Enter event handling responsibility from
`SelectableList` to the individual `SelectableListItem` components.
Closes [512](https://github.com/twentyhq/core-team-issues/issues/512)

## Key Changes:
- All dropdowns are now navigable with arrow keys

## Technical Implementation:
- Each `SelectableListItem` now has direct access to its own `Enter` key
handler, improving component encapsulation
- Removed the central `Enter` key handler logic from `SelectableList`
- Added `SelectableList` and `SelectableListItem` to all `Dropdown`
components inside the app
- Updated all component implementations to adapt to the new pattern:
  - Action menu components (`ActionDropdownItem`, `ActionListItem`)
  - Command menu components
  - Object filter, sort and options dropdowns
  - Record picker components
  - Select components

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-25 18:55:39 +02:00
0b1b81429e fix relation fields preview in settings (#11745)
Fixes :
- display relation fields in preview settings
- display note and task relation field in preview settings - 
- fix design (align and background color)

closes https://github.com/twentyhq/twenty/issues/7084

---------

Co-authored-by: guillim <guigloo@msn.com>
2025-04-25 18:26:27 +02:00
MarieGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
11d9d964cc Add upgrade instructions since v0.50.0 (#11748)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-25 18:22:59 +02:00
GuillimandGitHub 95808b06b9 Messaging-logging (#11723)
parseBatchResponse:
we need more logs to understand why we have some empty repsonse in the
body.

For anothe PR:  
~~UNKNOWN_NETWORK_ERROR : moving from handleUnknownException to
handleTemporaryException. This is important since in the logs I saw "The
service is currently unavailable" which makes me think we should handle
this type of error with as temporary~~
2025-04-25 18:01:53 +02:00
Félix MalfaitandGitHub dd446ef441 Fix CSV upload (#11749)
I inadvertently broke the upload button on the CSV import
2025-04-25 17:49:50 +02:00
Thomas des FrancsandGitHub 904558e7bb 0.52.0 changelog (#11743) 2025-04-25 17:20:30 +02:00
Raphaël BosiandGitHub 5207836566 Table hover and click outside fixes (#11737)
# Table hover and click outside fixes

This PR improves table interaction behavior by refining cell hover
states and click-outside handling in the record table component.

## Changes

### Click Outside Handling
- Removed conditional rendering of
`RecordTableBodyFocusClickOutsideEffect`

### Hover State Management
Implemented hover state cleanup in multiple components:
- Added `recordTableHoverPosition` state reset in `useLeaveTableFocus`
hook
- Integrated mouse leave handler in `RecordTableBodyDroppable` to clear
hover position

### Fixes double focus bug
- Reset the focus and the hover when the table data changes

## Videos

### Before


https://github.com/user-attachments/assets/f815b65c-c545-4841-a0d9-04c58771e69f

### After


https://github.com/user-attachments/assets/046cc7df-18b8-46ca-b2cc-bdfa3125311b
2025-04-25 16:50:48 +02:00
Félix MalfaitandGitHub 535a8d4410 Fix workflow preview environment repository dispatch (#11739)
This is hard to test without merging PRs unfortunately

Goal of this PR is to replace the action I had introduced since there
was already a similar one in the codebase
2025-04-25 15:52:12 +02:00
Félix MalfaitandGitHub 3fc498dba7 Attempt to add preview environments (#11734)
Just doing a quick test
2025-04-25 15:42:40 +02:00
GuillimandGitHub 1ff9f35b35 Record name missing when being created from a filter (#11733)
name of record not appearing when being created from a filter

Before :  
<img width="223" alt="Screenshot 2025-04-25 at 10 48 27"
src="https://github.com/user-attachments/assets/e3c7cc05-8664-4c14-bcaa-d5b045eb8311"
/>

After :  
<img width="236" alt="Screenshot 2025-04-25 at 10 48 53"
src="https://github.com/user-attachments/assets/778e02e0-0451-4125-b13e-0c2ac222ef41"
/>
2025-04-25 12:59:15 +00:00
Félix MalfaitandGitHub c66b7afefb Update cache policy (#11732)
I couldn't reproduce
https://github.com/twentyhq/twenty/issues/9299#issuecomment-2576868142
anymore

Closes #4914
2025-04-25 11:18:48 +02:00
Charles BochetandGitHub 0c8eb149e6 Refactor new relation sync (#11711)
In this PR:
- this should fix the sync metadata for new relation system

This goes with the recent PR:
https://github.com/twentyhq/twenty/pull/11725

What we want:
- ONE_TO_MANY relations should have no joinColumn and no onDelete
- MANY_TO_ONE should have both
2025-04-25 01:02:49 +02:00
9fb7ef5d47 Automatically Apply Values on Filtered Views (#11717)
Issue : When I create a task in the "Assigned to me" task view, it will
disappear from the view because the Assignee field isn't automatically
populated.

Solution :
We created a "buildRecordInputFromFilters" funciron that will convert
filtered into their corresponding values for the input.


Fixes https://github.com/twentyhq/core-team-issues/issues/708

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-04-24 19:02:03 +02:00
martmullandGitHub 4d7dbb1991 Fix missing on delete cascade for relation (#11725)
Follow up from https://github.com/twentyhq/twenty/pull/10217
Adding onDelete action on Many_to_one sides
2025-04-24 18:32:14 +02:00
c0df96b383 i18n - translations (#11727)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-24 18:21:21 +02:00
MarieandGitHub e750ef28a1 [permission] Override query builders db-executing methods (#11714)
closes https://github.com/twentyhq/core-team-issues/issues/843
2025-04-24 18:20:21 +02:00
WeikoandGitHub e55ecb4dcd object level override form (#11672) 2025-04-24 18:15:43 +02:00
Baptiste DevessierandGitHub 48e2581581 Stop persisting JSON fields in workflow runs (#11715)
## Before


https://github.com/user-attachments/assets/903c5771-ac15-49a6-9175-40c8b027655b

## After


https://github.com/user-attachments/assets/26aedf77-31ac-439a-a39c-57a274010f3f
2025-04-24 17:02:26 +02:00
6a75420285 i18n - translations (#11724)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-24 17:01:09 +02:00
Paul RastoinandGitHub 8b63d45b70 Fix missing ObjectRecordId param (#11721)
# Introduction
Fixes https://github.com/twentyhq/twenty/issues/11718

From having
[noUncheckedIndexedAccess](https://www.typescriptlang.org/tsconfig/#noUncheckedIndexedAccess)
set to false we have a flakiness resulting in a such bug right here as
the below operation can return `undefined` but not type as it should:
```ts
  const recordId = allRecordIds[position.row];
```

About to create a Tech project about the topic, activating the flag ends
in 1500 typescript erros from the style solution compilation ( which
means can contains several duplicated errors )
2025-04-24 16:49:56 +02:00
Félix MalfaitandGitHub 5343dd62d6 Update readme with partner logos (#11722)
Recognize the role of Greptile/Sentry/Crowdin/Chromatic which give
generous open source plans + some cleanup
2025-04-24 16:09:43 +02:00
Raphaël BosiandGitHub 4a61956087 Fixes on record title input (#11720)
- Fix record creation title cell opening
- Fix full name input hotkey scope
2025-04-24 15:29:21 +02:00
Paul RastoinandGitHub b545ebc53b Hide toggle isSyncLabelName for standardObject field edition (#11713)
# Introduction
closes https://github.com/twentyhq/core-team-issues/issues/880
2025-04-24 13:51:10 +02:00
Baptiste DevessierandGitHub cc211550ae Workflow runs in side panel (#11669)
Vidéo explicative : https://share.cleanshot.com/VsvWknlW

Closes https://github.com/twentyhq/core-team-issues/issues/810
Closes https://github.com/twentyhq/core-team-issues/issues/806

Known issues to fix later:

- https://github.com/twentyhq/core-team-issues/issues/879
2025-04-24 11:33:17 +02:00
Paul RastoinandGitHub 0083569606 Fix object model settings label synchronization (#11708)
# Introduction
Closes https://github.com/twentyhq/twenty/issues/11150
2025-04-24 10:58:59 +02:00
EtienneandGitHub ccc6d968aa update price on subscription - command (#11698) 2025-04-24 09:32:03 +02:00
Félix MalfaitandGitHub 0b729cb000 Fix json type in clickhouse migrations (#11710)
Settings in clickhouse are only set for the duration of the session so
we need to keep the same client
2025-04-23 22:08:52 +02:00
Félix MalfaitandGitHub cec17a3ebe Fix clickhouse migration not in dist (#11709)
Clickhouse migrations were not correctly copied to the dist folder (for
command yarn clickhouse:migrate:prod)
2025-04-23 21:16:30 +02:00
Charles BochetandGitHub 8076ff5b82 Fix broken metadata sync due to index removal (#11706)
Changing strategy regarding disabling index creation with new relation
system
2025-04-23 18:06:19 +02:00
MarieandGitHub 4257f30f12 Permission checks on twentyORM global manager (#11477)
In this PR we are handling permissions when using
twentyORMGlobalManager,
and handling permissions for rest api and api key
2025-04-23 17:57:48 +02:00
Thomas TrompetteandGitHub 28a1354928 Allow webhook only on active versions (#11705)
- webhook call should only be allow on active versions
- fixing exceptions that are wrongly sent to sentry
2025-04-23 17:28:41 +02:00
Charles BochetandGitHub a2d2db441f Improve Filter chip empty state (#11704)
Cases:

<img width="477" alt="image"
src="https://github.com/user-attachments/assets/06da3efc-b878-499f-97de-570317caa9b7"
/>

<img width="477" alt="image"
src="https://github.com/user-attachments/assets/40114c16-2810-489d-a60f-2579e2916691"
/>

<img width="477" alt="image"
src="https://github.com/user-attachments/assets/fa80d7cf-7c2d-4c19-919e-2d4c78a9202b"
/>
2025-04-23 16:54:11 +02:00
Charles BochetandGitHub a4882089b1 Add is relation enabled to default feature flags (#11703) 2025-04-23 16:26:53 +02:00
Paul RastoinandGitHub f2828883ad Fix click outside dropdown content confirmation modal (#11702)
# Introduction
Closes https://github.com/twentyhq/twenty/issues/11674
2025-04-23 14:23:15 +00:00
Thomas TrompetteandGitHub 1333c64d98 Add diff in workflow update events + fix existing (#11700)
Closes https://github.com/twentyhq/twenty/issues/11676.

Diff should be available for objects displaying timeline activities. It
should also fit the existing type.
2025-04-23 15:43:41 +02:00
Félix MalfaitandGitHub e1054b0474 Fix clickhouse migration (#11699)
It looks like Clickhouse Cloud uses a different config var than the docs
2025-04-23 15:09:23 +02:00
Charles BochetandGitHub 457c6ed113 Improve storybook stories (#11694)
## Improvements

### TaskGroups

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/0dbd71fe-3999-4cf5-870e-565b8e2df1b9"
/>

### EventCardMessage

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/b41cddc1-3ff2-411f-9ac6-8d4035579e54"
/>

### Blocklist stories

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/e997a0c1-e7e2-4ea4-9253-f31609ee44df"
/>

### WorkflowEditActionUpdateRecord

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/275dab17-ad33-4174-8671-31ba455c20a4"
/>
2025-04-23 13:20:13 +02:00
Félix MalfaitandGitHub 93c2ba153b Add clickhouse prod migration command (#11695)
Add a missing command to launch clickhouse migrations the same way we
launch postgres migrations
2025-04-23 13:02:00 +02:00
martmullandGitHub b6e8103df7 Mime encode names in email headers (#11691)
# Before
<img width="618" alt="image"
src="https://github.com/user-attachments/assets/e6d7c0ac-10f8-4d2e-abe4-05bf86a2ea9e"
/>

# After
<img width="504" alt="image"
src="https://github.com/user-attachments/assets/db147cb9-be19-4d08-b357-cb554dc2a4ae"
/>

Fixes also Emojis encoding in Subject ->
<img width="540" alt="image"
src="https://github.com/user-attachments/assets/8c27743f-3a50-46eb-b0f3-492219bbd646"
/>

 Works with microsoft accounts
<img width="360" alt="image"
src="https://github.com/user-attachments/assets/d924440f-c107-4c1c-ad4d-b4b27016f102"
/>


Fixes https://github.com/twentyhq/twenty/issues/9194
2025-04-23 11:37:40 +02:00
EtienneandGitHub ea850f323a Fix inline cell interactions (#11686)
@bosiraphael I've slightly updated [your recent
pr](https://github.com/twentyhq/twenty/pull/11654)
- before
<img width="490" alt="Screenshot 2025-04-22 at 17 48 26"
src="https://github.com/user-attachments/assets/604d65df-5433-4524-bdc5-6f5083b3c045"
/>

- after
<img width="488" alt="Screenshot 2025-04-22 at 17 47 41"
src="https://github.com/user-attachments/assets/21273372-538e-454e-947b-09373d9e0d6d"
/>


closes https://github.com/twentyhq/core-team-issues/issues/831 and
https://github.com/twentyhq/core-team-issues/issues/828
2025-04-23 08:46:10 +00:00
Charles BochetandGitHub fa5f758228 Fix storybook / chromatic tests flakyness and integration tests (#11687)
## Storybook flakyness

### Actor Display image flakyness

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/875c0738-5e31-4aba-9231-4ba5f78d1355"
/>

**Fix:** stop using a random usage

### Task Groups broken

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/c67e47a1-a027-43f1-9601-68d61a8052b4"
/>

**Fix:** add missing TabListComponentInstance

## Flaky dates

Add https://github.com/k35o/storybook-addon-mock-date

## Integration tests

Fix broken tests due to relation refactoring
2025-04-23 01:57:36 +02:00
Félix MalfaitandGitHub 8694840b92 Rename webhook and open api urls (#11684)
We want to have fewer base path for routing.

We will have:
- /files
- /webhooks
- /graphql
- /metadata
- /rest
- /auth
- /healthz

I'm moving /open-api under /rest, and centralizing the webhooks
(removing /stripe and /cloudflare)
2025-04-22 22:24:26 +02:00
Paul RastoinandGitHub fba9ae6dfe Fallback undefined recordDataChip record name to empty string (#11685)
# Introduction
Closes #11682 

This seems to always has been quite flaky but this latest
[update](https://github.com/twentyhq/twenty/commit/f0de6d31b7b3b84671c3a5af8fd047ef7432666f#diff-63704155b77d9690a87a1ebd9f364bab7e7bb12afed7cc5a5516561ec3798f29L20)
seems to made the name optional.

As previously `undefined` being transpiles to a string results in
`"undefined"` which not a good thing neither 🙃 but wouldn't throw before
2025-04-22 20:17:44 +02:00
cc29c25176 feat: new relation sync-metadata, twenty-orm, create/update (#10217)
Fix
https://github.com/twentyhq/core-team-issues/issues/330#issue-2827026606
and
https://github.com/twentyhq/core-team-issues/issues/327#issue-2827001814

What this PR does when `isNewRelationEnabled` is set to `true`:
- [x] Drop the creation of the  foreign key as a `FieldMetadata`
- [x] Stop creating `RelationMetadata`
- [x] Properly fill `FieldMetadata` of type `RELATION` during the sync
command
- [x] Use new relation settings in TwentyORM
- [x] Properly create `FieldMetadata` relations when we create a new
object
- [x] Handle `database:reset` with new relations

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-22 19:01:39 +02:00
Paul RastoinandGitHub de1489aabb Time line activity wrong type (#11673)
# Introduction
Closes https://github.com/twentyhq/core-team-issues/issues/874

`TimeLineActivity` fields `` and `` were typed as required whereas in
reality are nullable, resulting in the related sentry error.
Refactored the type then the related components in order to handle
nullable use case
2025-04-22 15:17:08 +00:00
Baptiste DevessierandGitHub efab98a8f8 Get all first depth fields in the table and the board (#11650)
After discussing it with the team, we now want to query all fields in
the table and the board by default. Feeding the cache with exhaustive
data will make the side panel's life easier, as it needs all the record
fields to determine the actions to enable.
2025-04-22 16:45:36 +02:00
Thomas TrompetteandGitHub 0b7024c94a Perform batch update on workflow runs (#11680)
Command times out on workflow versions with too many runs. Performing
batch update instead
2025-04-22 16:07:29 +02:00
EtienneandGitHub 5250d5c8d6 fix subscription item update (#11648)
closes
https://twenty-v7.sentry.io/issues/6550388239/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=issue-stream&stream_index=6
2025-04-22 14:01:36 +02:00
Raphaël BosiandGitHub 87083cb414 834 Design Adjustments for the Record Page Breadcrumb (#11670)
# Design Adjustments for the Record Page Breadcrumb

Closes [834](https://github.com/twentyhq/core-team-issues/issues/834)
and [826](https://github.com/twentyhq/core-team-issues/issues/826)

## Description

- Added the breadcrumb to every object (not just the workflows)
- Fixed spacings
- Changed icon color from primary to tertiary for proper visual
hierarchy
- Displayed pagination information (current/total)
- Close button has been removed to simplify the UI
- Navigate to index page when the breadcrumb is clicked
- Fixed problems when two record title cells were displayed at the same
time (in the header and in the record page)

## Before

<img width="247" alt="Capture d’écran 2025-04-22 à 12 15 34"
src="https://github.com/user-attachments/assets/5ca2aca7-ffb0-49ea-8d3a-4bd621d78f8d"
/>

## After

<img width="233" alt="Capture d’écran 2025-04-22 à 12 15 06"
src="https://github.com/user-attachments/assets/cbcb5dfe-d616-47c9-8017-71dd4d388534"
/>
2025-04-22 13:52:56 +02:00
Raphaël BosiandGitHub 251a7b126b 838 design adjustments on table kanban and inline fields (#11654)
Closes [#838]( https://github.com/twentyhq/core-team-issues/issues/838)
Design adjustments on table kanban and inline fields.

The table row border selection will be done later since it is harder
than initially thought.
2025-04-22 11:15:53 +02:00
Thomas TrompetteandGitHub 33e0794da9 Update workflow statuses in real time (#11653)
Statuses are maintained by an async job. Those are calculations that we
would like to avoid using in both frontend and backend. Using push
updates are an easier way.



https://github.com/user-attachments/assets/31e44a82-08a8-4100-a38e-c965d5c73ee8
2025-04-22 11:03:12 +02:00
Ken LynchandGitHub 3ce3793129 Update glossary.mdx (#11661)
Remove extraneous AI response. :)
2025-04-22 10:17:16 +02:00
Félix MalfaitandGitHub aa2f3438fa Fix email verification (#11660)
Email verification modal had been broken and looked bad

I also added stories to make it more evident if this happens again
2025-04-20 14:18:43 +02:00
Félix MalfaitandGitHub 24873d0c1d Remove versions from package.json (#11658)
Now the source of truth for the version is set during the build process.
We set it as an environment variable from the tags.
We could add it back to the package.json during the build process (from
the git tag), but there is not use for it at the moment since it's not
npm packages.
2025-04-19 23:03:06 +02:00
Antoine MoreauxandGitHub 83434deb22 refactor(auth): optimize work email handling in sign-up flow (#11655)
Extracted isWorkEmail check into a variable for reusability and adjusted
subdomain generation to conditionally include email. This enhances code
readability and maintains logic consistency.
2025-04-19 15:28:41 +02:00
Baptiste DevessierandGitHub 826889715b Fix e2e tests (#11656)
After @bosiraphael's updates on the table, cells are duplicated when
they get the hover/focus. Playwright has a hard time finding which
element to click on.
I dislike my solution because it doesn't mimic how a real user would use
the application, but I couldn't find a better solution that wasn't
flaky.
2025-04-18 18:39:43 +02:00
MarieandGitHub f8b9e4d780 ignoreLock when recomputing rolePermissions when creating datasource (#11657)
[sentry](https://twenty-v7.sentry.io/issues/6545999328/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=issue-stream&sort=date&stream_index=2)

Our workers have failing jobs because they are concurrently creating
datasources on different pods
While the datasources are independent, they read from the same redis
cache, with the same `RolesPermissionsOngoingCachingLock` value in
redis.
<img width="852" alt="Capture d’écran 2025-04-18 à 18 00 20"
src="https://github.com/user-attachments/assets/42ce8479-acc1-462b-af4c-b547cc2bb0b8"
/>
As a consequence they can fail to create a datasource: the first
datasource computes the permissions and sets ongoingCachingLock to true,
then the second arrives, there are still no available permissions in the
cache, but because of the lock it early returns without permissions and
fails. This behavior goes unnoticed on the product and helps
performances, but is annoying for workers as jobs are failing.

Let's remove the cache lock when creating the datasource !
2025-04-18 18:16:34 +02:00
8512904c0a refacto clickoutside componentv2 (#11644)
Switch to ComponentV2

Friday morning refacto & chill with @charles

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-18 17:48:30 +02:00
Félix MalfaitandGitHub cf5649a1df Deprecate Sentry release (#11651)
Let's deprecate Sentry Release and use APP_VERSION instead. 

It'll make it more clear in the interface to use named version for bug
analysis, than commit sha
2025-04-18 15:48:48 +02:00
martmullandGitHub fba4192d4b Fix rest api integration tests (#11645)
as title
2025-04-18 15:23:36 +02:00
16bd0425e0 i18n - translations (#11647)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-18 14:22:25 +02:00
MarieandGitHub fd750c7c0e Fix metadata cache flush (#11646)
Attempt to fix
https://twenty-v7.sentry.io/issues/6545999328/?environment=prod&project=4507072499810304&query=is%3Aunresolved%20issue.priority%3A%5Bhigh%2C%20medium%5D&referrer=issue-stream&sort=date&stream_index=2
2025-04-18 12:02:36 +00:00
Thomas TrompetteandGitHub 8112c3aab3 Fix workflow run executed by empty (#11642)
Workflow run executed by should not be empty when the workflow is
unamed. Adding Workflow as fallback

<img width="1072" alt="Capture d’écran 2025-04-17 à 19 17 12"
src="https://github.com/user-attachments/assets/e4cc3360-06e5-47e8-ba05-28a0eafab994"
/>
2025-04-18 09:26:51 +00:00
Antoine MoreauxandGitHub 8a2a004fb5 feat(settings): add domain validation effect and delete functionality (#11643)
Introduced a new effect component to validate custom domain DNS records
on mount, centralizing logic. Added a button to reset the custom domain
field, improving user control and form handling. Refactored related code
for maintainability and enhanced UI structure.

Fix https://github.com/twentyhq/core-team-issues/issues/853
2025-04-18 08:18:36 +00:00
oliverGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix MalfaitFélix Malfait
53042cc9dc Date field format display (#11384)
## Introduction

This PR enables functionality discussed in [Layout Date
Formatting](https://github.com/twentyhq/core-team-issues/issues/97).

### TLDR;
It enables greater control of date formatting at the object's field
level by upgrading all DATE and DATE_TIME fields' settings from:

```ts
{
    displayAsRelativeDate: boolean
}
```

to:

```ts

type FieldDateDisplayFormat = 'full_date' | 'relative_date' | 'date' | 'time' | 'year' | 'custom'

{
    displayFormat: FieldDateDisplayFormat
}
```

PR also includes an upgrade command that will update any existing DATE
and DATE_TIME fields to the new settings value

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-04-18 07:00:02 +00:00
Raphaël BosiandGitHub dd0ea2366f 839 Table focus refactoring (#11629)
# Table Focus Refactoring

This pull request implements the table focus refactoring requested in
[#839](https://github.com/twentyhq/core-team-issues/issues/839),
dissociating hover and focus behaviors in the table component to improve
keyboard navigation.

## Technical Implementation

- Created separate component states to handle focus and hover
independently.
- Updated all relevant hooks and functions to use the new focus
mechanism.
- Removed deprecated states and hooks.
- Introduced dedicated portal components to improve the table
performance (the table cells are much simpler and the more complex logic
is handled via the portals)

## Key Behavior Changes

- Performance improvements
- Focus is now handled exclusively with keyboard navigation
- Clicking on a cell or inline-cell now sets the focus to that cell
- Hover state is managed separately from focus, improving user
experience and accessibility
- The table scrolls when the focused cell changes

## Video



https://github.com/user-attachments/assets/9966beac-3b0f-4433-a87a-299506d83353
2025-04-17 16:40:24 +00:00
Thomas TrompetteandGitHub 18a89b5152 Set error on number field and prevent form from being submitted (#11637)
<img width="943" alt="Capture d’écran 2025-04-17 à 18 14 46"
src="https://github.com/user-attachments/assets/1208075e-937f-4224-886c-be578264d448"
/>
2025-04-17 18:39:18 +02:00
WeikoandGitHub 19da80d2e4 Fix logs in integration tests for unhandled exceptions without removing logger (#11635)
Setting a global exception filter for unhandled exceptions to avoid the
default Nest ExceptionsHandler being called (and logging exceptions)
2025-04-17 18:35:21 +02:00
WeikoandGitHub 3fe12cd8b5 Fix select default value not in options (#11622)
Also fixing a bunch of places where validation exceptions were not
properly handled
2025-04-17 18:34:31 +02:00
EtienneandGitHub dd1ac4deee Fix mismatching stripe subscription metadata plan/planKey (#11634)
for later : https://github.com/twentyhq/core-team-issues/issues/867
2025-04-17 18:21:35 +02:00
martmullandGitHub e4150ff3cb Fix logs in integration tests (#11632)
## Before
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/3e8be2e0-ac16-4735-8783-69c800bf0aaf"
/>

## After
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/1a83e7ce-d70a-43c4-a6cd-89dd456d80c1"
/>
2025-04-17 15:05:10 +00:00
Lucas BordeauGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
caf44207fd Implemented filter on FULL_NAME sub-fields (#11628)
This PR implements what's missing to have sub-field filtering.

There is a backend modification to save subFieldName, we just add this
field on view filter workspace entity.

This PR adds subFieldName where missing in frontend, notably in
applyFilter calls, that will be refactored soon.

Also fixes a bug in ViewBar where Add Filter button was at the right
side of the ViewBar, while it should be right after the chips section.

Another bug fixed where we wouldn't delete an empty record filter on
dropdown click outside from the view bar, which was already the case
where using the filter chip dropdown.

<img width="512" alt="image"
src="https://github.com/user-attachments/assets/e9a2f8d2-a66f-4800-853a-4df5c6b627a9"
/>

<img width="495" alt="image"
src="https://github.com/user-attachments/assets/7542697b-0689-4095-9c3c-b5e47875355f"
/>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-17 15:03:56 +00:00
Baptiste DevessierandGitHub 1ba0c24071 Set the page hotkey scope only once (#11626)
The `useEffect` in the `PageChangeEffect` component that sets the page's
hotkey scope is run 4-5 times every time the page changes. It should be
executed only once when the location changes. The re-runs are due to
unstable dependencies that shouldn't re-trigger the `useEffect`.

This PR minimizes the re-runs of the `useEffect`. In the following
video, I discuss a more global pattern.

The documentation for the `useEffectEvent` hook:
https://react.dev/learn/separating-events-from-effects#extracting-non-reactive-logic-out-of-effects.


https://github.com/user-attachments/assets/8c0c238b-f1c4-4bbb-b083-0825f7176599
2025-04-17 16:57:49 +02:00
Antoine MoreauxandGitHub 21c3edf8d6 fix(integration-tests): auth with multiworkspace and skip clickhouse … (#11630)
…tests
2025-04-17 14:49:57 +00:00
EtienneandGitHub a7b75c61e8 fix billing command - add workflow subscription item (#11631)
to migrate user with trialing or paused subscription status with trial
end behaviour 'paused'
2025-04-17 16:23:03 +02:00
f40aafb89f fix: reflect on #10521 changes to order-by-input-factory.ts file (#10662)
# This PR

Fixes an error on the FindMany REST API
I was getting the following error:
```
{
  "statusCode": 400,
  "error": "TypeError",
  "messages": [
    "Cannot read properties of undefined (reading 'fields')"
  ]
}
```
Now, it's working as expected
Related to #10521

cc: @Weiko @ijreilly

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-04-17 16:06:53 +02:00
42e060ac74 Ws poc (#11293)
related to https://github.com/twentyhq/core-team-issues/issues/601

## Done
- add a `onDbEvent` `Subscription` graphql endpoint to listen to
database_event using what we have done with webhooks:
- you can subscribe to any `action` (created, updated, ...) for any
`objectNameSingular` or a specific `recordId`. Parameters are nullable
and treated as wildcards when null.
  - returns events with following shape
```typescript
  @Field(() => String)
  eventId: string;

  @Field()
  emittedAt: string;

  @Field(() => DatabaseEventAction)
  action: DatabaseEventAction;

  @Field(() => String)
  objectNameSingular: string;

  @Field(() => GraphQLJSON)
  record: ObjectRecord;

  @Field(() => [String], { nullable: true })
  updatedFields?: string[];
```
- front provide a componentEffect `<ListenRecordUpdatesEffect />` that
listen for an `objectNameSingular`, a `recordId` and a list of
`listenedFields`. It subscribes to record updates and updates its apollo
cached value for specified `listenedFields`
- subscription is protected with credentials

## Result

Here is an application with `workflowRun`


https://github.com/user-attachments/assets/c964d857-3b54-495f-bf14-587ba26c5a8c

---------

Co-authored-by: prastoin <paul@twenty.com>
2025-04-17 16:03:51 +02:00
Thomas TrompetteandGitHub b112d06f66 Fix onClick on forms (#11624)
As title
2025-04-17 13:53:40 +00:00
Charles BochetandGitHub 56874bf84b Fix aggregate bar (#11620)
Closes https://github.com/twentyhq/twenty/issues/10943

Also adds stories:
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/377059b1-f6b5-4d8c-b7d1-e74e70448445"
/>
2025-04-17 15:29:20 +02:00
Thomas TrompetteandGitHub d2881bb4a2 Allow workflow field update when custom (#11619)
- Allow workflow field update when custom
- Also handle the case where object name is not defined in actions
2025-04-17 15:01:18 +02:00
GuillimandGitHub 1401f80081 Messaging : better logging (#11621)
Better error logging for messaging import exception handler.

Goal is to have better info on why Unknown errors are thrown and avoid
such messages `Unknown error occurred while importing messages for
message channel XXXXXXXX in workspace YYYYYYYYYY: Unknown error occurred
while importing messages for message channel XXXXXXXX...`
2025-04-17 14:16:05 +02:00
EtienneandGitHub 71dbd1d66b fix: re-init subscription items when user ends his trial period (#11616) 2025-04-17 13:53:37 +02:00
GuillimandGitHub 6e7956b990 logs removal (#11618)
view with Martin, not necessary any longer
2025-04-17 10:01:05 +00:00
martmullandGitHub 0469aba90b Improve from in send email action (#11581)
## Before
<img width="701" alt="image"
src="https://github.com/user-attachments/assets/77184775-5b06-4777-9276-1338cc457070"
/>

## After
<img width="705" alt="image"
src="https://github.com/user-attachments/assets/9528eb0e-54c3-452c-8297-27796ccc75a1"
/>
2025-04-17 11:34:55 +02:00
Antoine MoreauxandGitHub e457ade362 chore(constants): add TrackAnalytics to excluded operations (#11617)
Included TrackAnalytics in the list of excluded middleware operations.
This ensures consistent handling of operations that bypass middleware
processing.
2025-04-17 11:24:45 +02:00
Vaibhav DevereandGitHub 6023bda579 Drop await usage for now-synchronous encodeFileToken() (#11612)
### Remove unnecessary `await` from `encodeFileToken` calls (now
synchronous) #11611

####  Context

In [PR #11385 – commit
26c17f3](https://github.com/twentyhq/twenty/pull/11385/commits/26c17f3205eb0cf4b93dd37cfec97638596ed263),
`FileService.encodeFileToken()` was updated to be a **synchronous**
method. However, several places in the codebase were still calling it
using `await`.

####  Changes 
This PR cleans up those redundant `await` usages to:
- Improve clarity
- Avoid confusion (no longer awaiting a non-Promise)
- Slightly reduce overhead in affected functions
- Removed `await` from calls to `this.fileService.encodeFileToken(...)`
2025-04-17 10:55:54 +02:00
9e9ba73a43 better handling the function argument without touching it (#11614)
leave intact the `input` argument to avoid side effects on the parent
caller

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-17 08:54:56 +00:00
nitinandGitHub d89474d43b Fix tab icon alignment issue (#11613)
before:
![Screenshot 2025-04-17 at 13 40
00](https://github.com/user-attachments/assets/b29b3e6b-0185-4289-950c-37a24b63cb65)

after:
![Screenshot 2025-04-17 at 13 39
49](https://github.com/user-attachments/assets/af2efe6f-3908-40d6-acde-d2839a5a8ba2)
2025-04-17 10:29:51 +02:00
GuillimandGitHub b5e6600c73 Capitalize labels objectmetadata (#11609)
Capitalize labels singular and plural from objectmetadata

Fixes [#664](https://github.com/twentyhq/core-team-issues/issues/664)
2025-04-16 21:02:12 +00:00
thomasdnGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
3ad110da33 Added support for podman deployment (#11600)
Added files needed to deploy twenty on podman using podman-compose.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-16 22:08:14 +02:00
Antoine MoreauxandGitHub 587281a541 feat(analytics): add clickhouse (#11174) 2025-04-16 16:33:10 +00:00
b6901a49bf Fix-inline-height (#11608)
Follow up from inline height #11553 related to PR #11442


we had some issues with hover styles

Fixes
https://github.com/twentyhq/twenty/issues/11442#issuecomment-2805893663

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-16 17:49:04 +02:00
e1b99a6f39 Fix Account Owner Dropdown to Display Team Member Profile Pictures #11370 (#11385)
#11370  & #11402
### Changes made:
1. Updated search.service.ts to properly handle workspace member avatar
and Person Avatar URLs with authentication tokens
2. Integrated FileService for token generation
3. Added FileModule to SearchModule for dependency injection

### Implementation details:
- Used getImageUrlWithToken to append authentication tokens to avatar
URLs specifically for workspace members

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-04-16 17:46:37 +02:00
MarieandGitHub 4d78f5f97f [permissions] Improve performances using a cache for userWorkspaces roles (#11587)
In this PR we are 

- introducing a cached map `{ userworkspaceId: roleId } `to reduce calls
to get a userWorkspace's role (we were having N+1 around that with
combinedFindMany queries and generally having a lot of avoidable
queries)
- using the roles permissions cache (`{ roleId: { objectNameSingular:
{ canRead: bool, canUpdate: bool, ...} } `) in Permissions V1's
userHasObjectPermission, in order to 1) improve performances to avoid
calls to get roles 2) start using our permissions cache
2025-04-16 17:07:43 +02:00
Félix MalfaitandGitHub ab277476a8 Remove Sentry fingerprint (#11602)
As discussed this @ijreilly, Fingerprinting is probably not needed and
Sentry will do a better job by itself
2025-04-16 16:25:40 +02:00
nitinandGitHub c95a84c8e5 update KeyValuePairType enum and add IS_CONFIG_VAR_IN_DB_ENABLED config var (#11596)
closes https://github.com/twentyhq/core-team-issues/issues/758
2025-04-16 16:23:57 +02:00
Thomas TrompetteandGitHub 78e10b2da5 Update next step ids on step update (#11605)
When inserting a new step between step 1 et step 2, then step 1 should
have the new step as next step id, add stop having step 2.

When deleting a step, we link the parent and next steps together. It may
change in the future
2025-04-16 15:30:05 +02:00
bf704bd1bc Improve CSV import sub-field selection (#11601)
This PR adds a better UX for selecting sub-fields when importing CSV
files.

Before : 

<img width="395" alt="image"
src="https://github.com/user-attachments/assets/5a599e7d-ed07-4531-8306-9d70e7cfa37d"
/>

After : 

<img width="298" alt="image"
src="https://github.com/user-attachments/assets/2be8a1df-d089-4341-970e-6db2b269141e"
/>

<img width="296" alt="image"
src="https://github.com/user-attachments/assets/584285f4-4e71-4abd-9adf-11819cab0dc5"
/>

- A util `getSubFieldOptionKey` has been made to be able to reference
the sub field in the `options` object of the spreadsheet import.
- New components have been created :
`MatchColumnSelectFieldSelectDropdownContent`,
`MatchColumnSelectSubFieldSelectDropdownContent` and
`MatchColumnSelectV2`
- Extracted the hard-coded option do not import into a constant
`DO_NOT_IMPORT_OPTION_KEY`
- Passed `availableFieldMetadataItems` to spreadsheet global options so
it's available anywhere in the hierarchy of components.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-16 15:08:24 +02:00
Baptiste DevessierandGitHub b1c0613514 Fix execution permissions (#11604)
The PR https://github.com/twentyhq/twenty/pull/11400 introduced changes
to the execution permissions of many executable files. These changes
aren't correct and must be reverted.

cc. @charlesBochet
2025-04-16 11:46:37 +02:00
GuillimandGitHub db8a60fe6f more logging to look at calendar errors (#11603)
Adding more logs to look at calendar errors that we have currently

Should help investigation on
https://twenty-v7.sentry.io/issues/5182547220/events/7e8b168887384ede8397e79c15adeb50/?project=4507072499810304
2025-04-16 11:46:02 +02:00
b7cfe89b14 Onboarding doc update (#11599)
Co-authored-by: Weiko <corentin@twenty.com>
2025-04-16 09:55:57 +02:00
madanlal mohanrao nikaljeandGitHub 4c2c9e4273 Refactor webhook event name generation in OpenApiService (#11592)
Fixes - #11589
POT - 
![Screenshot 2025-04-16 at 12 39
11 AM](https://github.com/user-attachments/assets/43802e1a-1ece-4b44-831f-35d70285c5fb)
2025-04-16 08:03:47 +02:00
Charles Bochet 981b1bd767 Fix stories 2025-04-15 23:41:30 +02:00
Charles Bochet 53c6ddb2ad Fix stories 2025-04-15 19:05:14 +02:00
EtienneandGitHub 6f78a51da4 fix query param init before workspace redirection (#11590) 2025-04-15 18:47:26 +02:00
WeikoandGitHub 43af5ceb5e Add object level permission permissions to role page (ReadOnly) (#11568)
## Context
This PR adds the display of object-level permissions. A following PR
will add the ability to update those permissions.
The PR contains the SettingsRoleObjectLevel page but it's not fully
implemented yet (save won't trigger the corresponding mutation)

<img width="616" alt="Screenshot 2025-04-14 at 18 02 40"
src="https://github.com/user-attachments/assets/f8c58193-31f3-468a-a96d-f06a9f2e1423"
/>
2025-04-15 18:46:36 +02:00
Baptiste DevessierandGitHub c23942ce6f Order the workflow run's output properly in the JsonFieldDisplay (#11583)
In this PR:

- Order the workflow run's output in the JsonField Display; the order
should be: error, stepsOutput, flow
- Ensure the special characters are hidden in the JSON visualizer
- Add missing scenarios to Json Tree's stories as it ensures Chromatic
checks them


https://github.com/user-attachments/assets/2ca5ae1d-fdba-4327-bad2-246fd9d23cb9

Closes https://github.com/twentyhq/core-team-issues/issues/804
2025-04-15 18:40:53 +02:00
8bd7b78825 Moved Select Options to External Files (#11400)
This is a minor rework of PR #10738.

I noticed an inconsistency with how Select options are passed as props.
Many files use constants stored in external files to pass options props
to Select objects. This allows for code reusability. Some files are not
passing options in this format.

I modified more files so that they use this method of passing options
props. I made changes to:
- WorkerQueueMetricsSection.tsx 
- SettingsDataModelFieldBooleanForm.tsx 
- SettingsDataModelFieldTextForm.tsx 
- SettingsDataModelFieldNumberForm.tsx 
- PlaygroundSetupForm.tsx 
- ViewPickerContentCreateMode.tsx 

I also noticed that some of these files were incorrectly using
useLingui(), so I fixed the import and usage where needed.

---------

Co-authored-by: Beau Smith <bsmith26@iastate.edu>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-15 18:31:17 +02:00
EtienneandGitHub 797bb0559a create stripe customer before checking out + update on command (#11578)
two distincts fix in this PR

- add billing threshold for current users (in migration command)
- create stripe customer before checking out in order to enable cloud
user to create multiple workspaces (with associated stripe customer -
closes https://github.com/twentyhq/core-team-issues/issues/852)
2025-04-15 18:02:35 +02:00
Charles BochetandGitHub dee779179b Remove user action from waitFor in stories (#11588)
As per title:
- waitFor is a loop that waits for a condition to be filled, it should
be use to expect or in rare case to wait for element to be present in
the page (in most cases, you can use findByXXX)
- user actions should not be in this loop, otherwise they will be
triggered multiple times
2025-04-15 17:34:28 +02:00
Thomas TrompetteGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
c40baf036c Add command to backfill next step id on version and run steps (#11579)
- add next step id on step
- backfill next step id on step, except for the last one
- backfill flow for workflow run, when it exists

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-04-15 15:26:58 +00:00
GuillimandGitHub d3922a7f5b removing RecordTableEmptyStateByGroupNoRecordAtAll (#11584)
We found out that `RecordTableEmptyStateByGroupNoRecordAtAll` was used
only when `hasRecordGroups` was true in "RecordTableEmptyState"

However the only parent component is RecordTableEmpty and called
RecordTableEmptyState when `hasRecordGroups` was false

Fixes https://github.com/twentyhq/core-team-issues/issues/833

Meaning never called at all
2025-04-15 16:52:09 +02:00
Charles BochetandGitHub 3c189688d0 Fix stories (#11585)
<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/f77a006c-9538-4734-b80e-b58b9f5e7835"
/>
2025-04-15 16:11:31 +02:00
Lucas BordeauandGitHub aa399ca91e Fix a bug that overwrites currentRecordFilters when using URL filtered view (#11525)
This PR fixes a bug that happened when navigating to a filtered view
from a record show page related record section, clicking on 'All'.

The problem was that the QueryParamsFiltersEffect effect component was
overwriting the currentRecordFilter of a different object metadata item
than the current view.

Which when we navigated back on the original view, had emptied the
filters, while they shouldn't change if we only navigate without
refreshing the app.

Fixes https://github.com/twentyhq/core-team-issues/issues/657
2025-04-15 15:32:41 +02:00
GuillimandGitHub 5c23b52c0d multiline CSS aligned to the top (#11582)
Updating CSS for inline cells so that multilie works fine and are
aligned to the top

Fixes
https://github.com/twentyhq/core-team-issues/issues/757?issue=twentyhq%7Ctwenty%7C11495
2025-04-15 13:15:37 +00:00
Charles BochetandGitHub 7bab6cab41 Fix storybook and chromatic tests and fix Block editor custom slash menu positioning (#11580)
Storybook / Chromatic fixes:
- fix linaria twenty-ui style loading (since twenty-ui prebuild
refactoring)
- update prefetch view mocks
- add ability to disable hotkeys initialization in storybook to avoid
race condition

Custom slash menu positioning fix
2025-04-15 14:57:35 +02:00
Murali SinghandGitHub 9da2a74d9e Fix inline field height #11442 (#11553)
Screenshots:

![Image](https://github.com/user-attachments/assets/998f2a88-53ab-49ef-8bb5-c7bef9158b0d)


![Image](https://github.com/user-attachments/assets/218c8f4b-f8d1-4d49-8029-8f99113f01ec)


![Image](https://github.com/user-attachments/assets/1dfde61a-62bb-403a-af3d-fb99c16ab29e)

@Bonapara Can you confirm is this what you expected ?
2025-04-15 14:42:21 +02:00
Charles BochetandGitHub d6ae4d59f0 Various fixes charles 3 (#11573) 2025-04-15 13:45:04 +02:00
Antoine MoreauxandGitHub f30070c2c9 feat(auth): enhance logo behavior and simplify billing logic (#11574)
Added default domain redirection functionality to the Logo component,
leveraging UndecoratedLink for navigation when default logos are used.
Removed metered product billing feature flag logic in the billing
webhook subscription service to simplify and streamline the codebase.

Fix https://github.com/twentyhq/core-team-issues/issues/783
2025-04-15 13:43:13 +02:00
GuillimandGitHub e1ce98825b Possiblity to reconnect on Failed unkown (#11576)
Possiblity to reconnect you account on Failed Unkown errors.

This PR triggers a similar flow than the Failed errors for unsufficient
permission already existing in twenty.

Allows our users to force the synchro again even though they have a
strange error. It's been asked by some customers since we have had a
couple of issues in messaging lately

Fixes https://github.com/twentyhq/twenty/issues/11411
2025-04-15 13:39:18 +02:00
e8db0176a1 Remove recoil sync (#11569)
Recoil-sync was causing issues with Firefox, replacing it with a simpler
mechanism to hydrate variables on page load

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-04-15 13:32:12 +02:00
Baptiste DevessierandGitHub 6c2d64dcb2 Fix e2e tests (#11577) 2025-04-15 12:16:38 +02:00
EtienneandGitHub 8b10059e1b fix - remove isMeteredProductBillingEnabled (#11575) 2025-04-15 11:15:02 +02:00
16fb4d406b i18n - translations (#11572)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-14 18:49:45 +02:00
Raphaël BosiandGitHub 8f2dddaa5f Create stories for action display components (#11547)
Create stories for:
- ActionButton
- ActionComponent
- ActionDisplay
- ActionDropdownItem
- ActionListItem
2025-04-14 18:42:49 +02:00
EtienneandGitHub 0249cf3b34 remove feature flag on billing metered product + fixes (#11570)
- remove feature flag
- design fixes
2025-04-14 18:39:19 +02:00
EtienneandGitHub 9a69cd0b61 add billing threshold + specific trial free credits (#11533)
In this PR : 
- set billing thresholds after subscription creation (not possible
during billing checkout)
- add specific free trial workflow credit quantities + set them in
subscription item + check them when receiving stripe alert event

closes : https://github.com/twentyhq/core-team-issues/issues/682
2025-04-14 16:25:07 +00:00
Baptiste DevessierandGitHub 704b18af30 Create FormRichTextField (#11474)
This PR adds a new Form Field for Rich Text V2 fields. The
implementation was relatively simple, thanks to @thomtrp's job on the
back-end side.

## Demo

### Edit mode + insert in database


https://github.com/user-attachments/assets/f44a6442-fad3-4ad9-af50-a7d90e872c90

### Readonly mode


https://github.com/user-attachments/assets/66243ddf-d4a2-4187-894c-356d9c02b2b2

Closes https://github.com/twentyhq/private-issues/issues/229
2025-04-14 18:07:09 +02:00
Baptiste DevessierandGitHub 0be700f376 Fix e2e tests (#11565)
Fixing the e2e tests
2025-04-14 17:47:57 +02:00
GuillimandGitHub 8a3f8ef324 Chip untitled modification (#11498)
Fixes https://github.com/twentyhq/core-team-issues/issues/663
2025-04-14 15:33:41 +00:00
MarieandGitHub d4deca45e8 Read feature flags from cache (#11556)
We are now storing a workspace's feature flag map in our redis cache. 
The cache is invalidated upon feature flag update through the lab
resolver.
2025-04-14 17:31:13 +02:00
Charles BochetandGitHub 15eb96337f Various fixes (#11567)
In this PR:
- Remove SignUpLoading blank screen by an empty dark overlay =>
VerifyEffect
- Add ModalContent from pages themselves instead of using it the Layout.
This allow for empty dark overlay without showing an empty modal with
padding
2025-04-14 17:24:16 +02:00
85d94822b3 Fix the Command menu items right padding #11484 (#11489)
Screenshot:
![Screenshot 2025-04-10 at 1 07
24 AM](https://github.com/user-attachments/assets/1e7ed8e7-594f-4ead-9b04-0c7dab636fbd)

---------

Co-authored-by: guillim <guigloo@msn.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-14 14:12:15 +02:00
Thomas TrompetteandGitHub 69a00eaaf6 Emit message event with actual message object (#11548)
Events were emitted with the wrong object. We were using
messageWithParticipant instead of actual message object
2025-04-14 13:49:19 +02:00
abecdbafc1 Add Edit Rich Text functionality to table view (#11390)
Fixes https://github.com/twentyhq/core-team-issues/issues/729


[recording.webm](https://github.com/user-attachments/assets/ea95d67b-64a3-4fef-91ed-b06318099a78)

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-14 11:46:22 +00:00
Charles BochetandGitHub 8f7a82f177 Fix refactor selectableList broke hotkey onEnter behavior (#11562) 2025-04-14 12:25:54 +02:00
4a123a8eac i18n - translations (#11560)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-14 11:11:30 +02:00
ace515eea7 Fix workflow with manual triggers and no selection not appearing in the command menu (#11544)
Fix workflow with manual triggers and no selection not appearing in the
command menu

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-14 11:03:29 +02:00
Lucas BordeauandGitHub b5a1d1a895 Improving empty filter chip UI (#11537)
This PR is simply removing the : character on the filter chip when the
filter value is empty.

The issue originally was about removing the filter chip when closing the
filter value dropdown with an empty value but it is already the default
behavior.

Fixes https://github.com/twentyhq/core-team-issues/issues/658
2025-04-14 10:43:20 +02:00
EtienneandGitHub 721a34864f create workflow subscription item addition command (#11541)
closes https://github.com/twentyhq/core-team-issues/issues/541
2025-04-14 10:41:37 +02:00
e2b2697fcc refacto dropdown v1>v2 in address input (#11549)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-14 10:37:40 +02:00
0de8140b3a CreateComponentFamilyState -> createComponentFamilyStateV2 (#11546)
Refacto of createComponentFamilyState

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-14 10:31:30 +02:00
Thomas TrompetteandGitHub 27f542e132 Use transformer in workflows (#11497)
We do not manage rich text properly in workflows. This is because API
has a layer called transformer service. Looks a bit as a duplicate of
format data, but this api layer was already there for position anyway.
Using it in workflow record actions.

I hope at some point we merged formatData util and transformer.
2025-04-11 16:31:45 +00:00
Baptiste DevessierandGitHub 897684f995 JSON Visualizer: ensure labels are 24px tall as all other elements (#11535)
## Before

![CleanShot 2025-04-11 at 14 42
15@2x](https://github.com/user-attachments/assets/a4726342-212a-40b3-829f-40cae7724fec)

## After

![CleanShot 2025-04-11 at 14 42
27@2x](https://github.com/user-attachments/assets/e84a4d81-fdcc-422e-b294-55867a4bc5fb)
2025-04-11 18:25:29 +02:00
MarieandGitHub 162c6bcaa3 [permissions] Implement object-records permissions in query builders (#11458)
In this PR we are

- (if permissionsV2 is enabled) executing permission checks at query
builder level. To do so we want to override the query builders methods
that are performing db calls (.execute(), .getMany(), ... etc.) For now
I have just overriden some of the query builders methods for the poc. To
do so I created custom query builder classes that extend typeorm's query
builder (selectQueryBuilder and updateQueryBuilder, for now and later I
will tackle softDeleteQueryBuilder, etc.).
- adding a notion of roles permissions version and roles permissions
object to datasources. We will now use one datasource per roleId and
rolePermissionVersion. Both rolesPermissionsVersion and rolesPermissions
objects are stored in redis and recomputed at role update or if queried
and found empty. Unlike for metadata version we don't need to store a
version in the db that stands for the source of truth. We also don't
need to destroy and recreate the datasource if the rolesPermissions
version changes, but only to update the value for rolesPermissions and
rolesPermissionsVersions on the existing datasource.

What this PR misses
- computing of roles permissions should take into account
objectPermissions table (for now it only looks at what's on the roles
table)
- pursue extension of query builder classes and overriding of their db
calling-methods
- what should the behaviour be for calls from twentyOrmGlobalManager
that don't have a roleId?
2025-04-11 17:34:02 +02:00
martmullandGitHub 82fa71c2cd Update canary package versions (#11543)
as title
2025-04-11 16:48:41 +02:00
WeikoandGitHub 04f9c5a5de Prepare 0.51 (#11542) 2025-04-11 16:00:24 +02:00
Charles BochetandGitHub 3018e3ac89 Fix date picker month/year dropdown (#11539)
Fixes https://github.com/twentyhq/twenty/issues/11524
2025-04-11 15:22:00 +02:00
GuillimandGitHub 2a8defe262 contact/company creations errors (#11540)
Seeing a couple of issues related to company creations in logs, I
suspect this to be the root cause

This should help a lot in all the support we have to do on email
synchronisation
2025-04-11 15:19:03 +02:00
Charles BochetandGitHub 9da5cca82a Fix dropdown width (#11536)
Fix regressions due to dropdown refactoring
2025-04-11 14:59:57 +02:00
Lucas BordeauandGitHub fe98deef4e Fixed command menu hotkey listener refactor (#11534)
This PR fixes a refactor that was done recently to avoid having
clickoutside listeners on the closed command menu.

The useScopedHotkey hook should have stayed in the command menu
container, because it should always listen.

This has been fixed.
2025-04-11 14:59:48 +02:00
03800ce6d0 i18n - translations (#11532)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-11 14:42:45 +02:00
martmullandGitHub 1794b3a611 Remove build lambda at creation (#11531)
Remove useless build call (done at first execution)
2025-04-11 14:40:00 +02:00
Baptiste DevessierandGitHub e8488e1da0 Only display Flow for Workflow Runs and display Output tab for triggers (#11520)
> [!WARNING]
> I refactored a bunch of components into utility functions to make it
possible to display the `WorkflowStepHeader` component for **triggers**
in the `CommandMenuWorkflowRunViewStep` component. Previously, we were
asserting that we were displaying the header in `Output` and `Input`
tabs only for **actions**. Handling triggers too required a bunch of
changes. We can think of making a bigger refactor of this part.

In this PR:

- Only display the Flow for Workflow Runs; removed the Code Editor tab
- Allows users to see the Output of trigger nodes
- Prevent impossible states by manually setting the selected tab when
selecting a node

## Demo

### Success, Running and Not Executed steps


https://github.com/user-attachments/assets/c6bebd0f-5da2-4ccc-aef2-d9890eafa59a

### Failed step


https://github.com/user-attachments/assets/e1f4e13a-2f5e-4792-a089-928e4d6b1ac0

Closes https://github.com/twentyhq/core-team-issues/issues/709
2025-04-11 14:31:34 +02:00
Raphaël BosiandGitHub c8011da4d7 Fix title input hotkey scope (#11530)
Before:


https://github.com/user-attachments/assets/e0be8247-6d3e-49d0-8595-76f9547bf354


After:


https://github.com/user-attachments/assets/ae23b01b-3ad7-4b90-b4ae-ce604d984d73
2025-04-11 14:22:31 +02:00
446919bc72 Remove onboarding flashes + close all dropdowns on CommandMenu close (#11483)
## Remove onboarding flashes

Tested:
- sign in with credentials
- sign in with social oAuth
- sign up with credentials
- multidomain
- single domain
- reset password

No more flashes, and code logic simplified!

## Close all dropdowns on CommandMenu close

Before:


https://github.com/user-attachments/assets/244ff935-3d40-47d5-a097-12d4cc3810dd


After:


https://github.com/user-attachments/assets/1de692f8-5032-404a-be74-025ebca67138

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-11 14:15:14 +02:00
Raphaël BosiandGitHub 637a7f0e64 Fix workflow dropdown hotkey scope (#11518)
The hokey scope was set on focus of the outermost container of the field
inputs. When clicking on a dropdown inside this container, the hokey
scope was set first by the dropdown and then by the focused container.
This led to the previous hotkey scope being overwritten.
The fix consists in moving the hokey scope setter on focus to the inner
container.

Before:


https://github.com/user-attachments/assets/12538c5b-43ab-4b76-a867-7eda6992b1ea


After:


https://github.com/user-attachments/assets/002fedba-010c-41e9-bec6-d5d80cb2dcc5
2025-04-11 09:07:36 +00:00
d34ec7b253 Fix: "Not shared" label not visible due to extra long email subject (#11492)
Closes #11408 

- Added `min-width: 100px` in `EmailThreadNotShared`
- Added `isShared` prop to `StyledSubject` for better subject handling
in shared visibility scenarios

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-11 10:13:33 +02:00
Thomas des FrancsandGitHub 04168e720c Update 0.51.0.mdx (#11517) 2025-04-11 10:12:31 +02:00
nitinandGitHub 0cccb80221 revert: transform -> marginLeft in DefaultLayout motion div (#11522) 2025-04-10 22:33:12 +02:00
Félix MalfaitandGitHub e6bb3d4d51 Change required permission for MS (#11519)
Change User.Read.All to User.Read in docs
2025-04-10 18:33:37 +02:00
Thomas des FrancsandGitHub 5a8006f1dd Update src/content/releases/0.51.0 2025-04-10 18:17:08 +02:00
martmullandGitHub b8406820ee Fix wrong filter for get requests (#11512)
- remove wrong exception filter for GET api requests
- remove messageThreadId requirements on messages for requests done with
API key (no user, only workspace)
- doing the same for calendarEvents
2025-04-10 17:29:53 +02:00
3e1b5d23f5 i18n - translations (#11515)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-10 17:10:55 +02:00
bc8f71fab5 wip: api playground fixes (#11345)
# ISSUE 
- closes #10926 

- [x] fix paddings
- [x] fix page change to playground animation
- [x] fixes multiple skeletons issues

---

- Also was showing multiple skeletons on reloading, **before**: 


https://github.com/user-attachments/assets/0cdef639-c121-4cbb-b056-b89e60862c54

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-10 17:02:55 +02:00
a86317eb71 i18n - translations (#11514)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-10 17:01:13 +02:00
EtienneandGitHub ee5aa2393d fix billingCheckoutSession query param + enable redirect on workspace… (#11509)
… during onboarding



fixes : https://github.com/twentyhq/core-team-issues/issues/668
2025-04-10 16:47:40 +02:00
WeikoandGitHub d69932c6c4 Fix boolean default value update not updating psql default value when false (#11513)
Fixes https://github.com/twentyhq/twenty/issues/11471

## Context
When sending false as a new defaultValue, this was not going through the
migration creation code due to this condition
```typescript
if (updatableFieldInput.defaultValue)
```
2025-04-10 16:23:16 +02:00
Thomas TrompetteandGitHub 6f5118c677 Remove fixed width for dropdown variables, fix optimistic on file upload (#11507)
As title
2025-04-10 16:07:32 +02:00
Lucas BordeauandGitHub f8f11894e8 Introduce generic way to close any open dropdown on page location change (#11504)
In this PR we introduce a generic way to close any open dropdown
idempotently, with the hook useCloseAnyOpenDropdown.

We also introduce a generic hook useExecuteTasksOnAnyLocationChange that
is called each time the page location changes.

This way we can close any open dropdown when the page location changes,
which fixes the original issue of having advanced filter dropdown
staying open between page changes.

Fixes https://github.com/twentyhq/core-team-issues/issues/659
2025-04-10 16:00:50 +02:00
1844c39a99 i18n - translations (#11511)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-10 15:47:28 +02:00
WeikoandGitHub 35c6cb4f4a fix chromatic 1 (#11510) 2025-04-10 15:44:12 +02:00
WeikoandGitHub 63a165666a fix error messages margin (#11508)
## Context
Fixing error messages margin in various places
Reset password
<img width="453" alt="Screenshot 2025-04-10 at 15 17 00"
src="https://github.com/user-attachments/assets/7a0fb090-4029-415f-8733-0c9e3aa3c3f2"
/>
Api key
<img width="543" alt="Screenshot 2025-04-10 at 15 16 21"
src="https://github.com/user-attachments/assets/d8f8a348-84d3-44d7-8cea-863c3ddb02fc"
/>

Also setting overflow on api key label in api keys table
<img width="580" alt="Screenshot 2025-04-10 at 15 16 15"
src="https://github.com/user-attachments/assets/207df981-c906-4926-a56d-38167628267f"
/>
2025-04-10 15:36:59 +02:00
Thomas TrompetteandGitHub b8d5f6d4b0 Center empty state on record table (#11506)
as title
2025-04-10 15:05:49 +02:00
martmullandGitHub 4e4c0ddd3c Add command to update serverless layer (#11500)
New command to add packages to serverless -> Run into your terminal
`npx nx run twenty-server:command serverless:add-packages -p
stripe@17.0.0,@slack/web-api,@slack/oauth`

Will create a new layer folder, add packages in it and update the new
last_layer_version

<img width="1468" alt="image"
src="https://github.com/user-attachments/assets/da8ee77f-e512-4ceb-95bc-cfa979f3439c"
/>

Before
<img width="877" alt="image"
src="https://github.com/user-attachments/assets/35f6bb6c-2ebf-46fe-bd15-4e6352901fc8"
/>

After
<img width="938" alt="image"
src="https://github.com/user-attachments/assets/785af132-5e8c-4a9a-bc57-dffdcaaeec02"
/>
2025-04-10 14:53:59 +02:00
WeikoandGitHub 1802c30995 Fix workspace menu width varies (#11505)
Before


https://github.com/user-attachments/assets/cd386034-bddd-4452-bb7f-2b3749ba74d6

After


https://github.com/user-attachments/assets/07ab40b1-0f8d-4b80-b0db-ad1ea8c584f7
2025-04-10 14:47:40 +02:00
Thomas TrompetteandGitHub 5b1091b19e Store trigger output (#11503)
As title. Trigger output is the workflow payload
2025-04-10 14:36:15 +02:00
cc6043be9f i18n - translations (#11502)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-10 14:11:46 +02:00
145ddba721 fix settings container vertical scroll position (#11464)
@charlesBochet is this flex needed here? we don't use flex-specific
properties.

I did check all scrolls seem to be working fine, could u please check
once more? thanks :)


before:
<img width="1512" alt="Screenshot 2025-04-09 at 12 59 25"
src="https://github.com/user-attachments/assets/1b0066e3-c3f7-4bd8-829b-174d2747ee66"
/>

after:
<img width="1512" alt="Screenshot 2025-04-09 at 12 58 13"
src="https://github.com/user-attachments/assets/06b103ed-d72f-4bc3-b530-7ae25542f568"
/>

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-10 14:11:21 +02:00
db88c93eff Navigation drawer refactor (#11251)
closes #11195
closes #11199

### Context

The yellow dots in the Settings Navigation Drawer (used to indicate
advanced settings) were being hidden due to ScrollWrapper's overflow
handling. This required both a fix for the visibility issue and an
improvement to the component structure.

### Changes
1. Keep scrolling logic of the MainNavigationDrawer and
SettingsNavigationDrawer in one place, and conditionally apply
`<StyledScrollableInnerContainer>` when isSettingsDrawer is true.

2. Fixed Yellow Dots Visibility
Added specific padding in NavigationDrawerScrollableContent to
accommodate yellow dots:
```
  padding-left: ${theme.spacing(5)}; // Space for yellow dots
  padding-right: ${theme.spacing(8)}; // Space for no-padding scroll
  ```
  
  This ensures the yellow dots are visible while maintaining proper scroll behavior

3. Improved Component Composition
Using proper component composition instead of passing components as props
Components are now composed in a more React-idiomatic way:
```
  <NavigationDrawer>
    <NavigationDrawerScrollableContent>
      <SettingsNavigationDrawerItems />
    </NavigationDrawerScrollableContent>
    <NavigationDrawerFixedContent>
      <AdvancedSettingsToggle />
    </NavigationDrawerFixedContent>
  </NavigationDrawer>
  ```

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-10 14:05:10 +02:00
WeikoandGitHub 41674129c3 Fix sign-in-up sso buttons width (#11499)
## Context
An enforced width was introduced recently for error texts but broke
Microsoft sso placement due to its longer text.
I've replaced it by a min-width and introduced the missing one in global
signin/up.

Before
<img width="456" alt="Screenshot 2025-04-10 at 12 14 51"
src="https://github.com/user-attachments/assets/43f29c63-f257-4c1c-9c16-b0170343c43e"
/>

After
<img width="494" alt="Screenshot 2025-04-10 at 12 14 17"
src="https://github.com/user-attachments/assets/17c4362a-1336-4adc-aeb9-76c6dcd059c6"
/>
2025-04-10 13:51:21 +02:00
Raphaël BosiandGitHub b84a31cb8a Create open side panel page action (#11481)
Closes https://github.com/twentyhq/core-team-issues/issues/697
2025-04-10 11:34:34 +02:00
Raphaël BosiandGitHub 4a4ce9a6fe Fix PageHeaderToggleCommandMenuButton (#11496)
This PR fixes a bug introduced by
https://github.com/twentyhq/twenty/pull/11470

Before:


https://github.com/user-attachments/assets/8c1b8114-591f-4b58-a177-551c4f0dfb98

After:


https://github.com/user-attachments/assets/b93aa498-2ae8-4001-b541-372866d24f54
2025-04-10 11:29:45 +02:00
Charles BochetandGitHub a7e6564017 Make token update synchronous on FE (#11486)
1. Removing tokenPair internal variable of ApolloFactory. We will relay
on cookieStorage
2. setting the cookie explicitely instead of only relaying on recoil
cookieEffect which is too late
2025-04-10 01:39:25 +02:00
WeikoandGitHub 7bd68ad176 Fix event propagation after record creation (#11485)
Fixes https://github.com/twentyhq/twenty/issues/11460
2025-04-10 01:37:26 +02:00
Lucas BordeauandGitHub 2b77f598b2 Fixed (#11482)
This PR fixes many small bugs around the recent hotkey scope refactor.

- Removed unused ActionBar files
- Created components CommandMenuOpenContainer and
KeyboardShortcutMenuOpenContent to avoid mounting listeners when not
needed
- Added DEFAULT_CELL_SCOPE where missing in some field inputs
- Called setHotkeyScopeAndMemorizePreviousScope instead of
setHotkeyScope in new useOpenFieldInputEditMode hook
- Broke down RecordTableBodyUnselectEffect into multiple simpler effect
components that are mounted only when needed to avoid listening for
keyboard and clickoutside event
- Re-implemented recently deleted table cell soft focus component logic
into RecordTableCellDisplayMode
- Created component selector isAtLeastOneTableRowSelectedSelector
- Drill down hotkey scope when opening a dropdown
- Improved debug logs
2025-04-09 18:34:31 +02:00
GuillimandGitHub 9f4e8c046f Messaging-unit-tests (#11467)
# Unit test on the Messaging Module

Initially the issue was to create integration test for the messaging
module but after speaking with the core team, we decided to go for an
easier implementation: unit test only,

We decided to focus our test on three main components of the module :  
- message list
- message import
- message save & create contact

Fixes https://github.com/twentyhq/core-team-issues/issues/56
2025-04-09 17:57:43 +02:00
Charles BochetandGitHub e23688cb41 Fix lint issues (#11475) 2025-04-09 17:35:25 +02:00
b6c079f050 Fixed Navbar padding issue #11438 (#11470)
@Bonapara 
Related Issue: Fixes #11438.

Screenshot:
![Screenshot 2025-04-09 at 4 10
41 PM](https://github.com/user-attachments/assets/4c5346b6-4e1c-4441-bd8a-b88aee139b9b)

---------

Co-authored-by: guillim <guigloo@msn.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-09 17:22:49 +02:00
Thomas TrompetteandGitHub 5d9cd257ae Command menu mobile - Prevent overflow on navigation bar (#11480)
Fix https://github.com/twentyhq/twenty/issues/11413
2025-04-09 17:16:46 +02:00
Thomas TrompetteandGitHub 025e50645d Avoid settings object cover image to be reduced on scroll (#11473)
Fix https://github.com/twentyhq/twenty/issues/11420
2025-04-09 16:43:25 +02:00
Raphaël BosiandGitHub 9e0402e691 Action menu refactoring (#11454)
# Description

Closes [#696](https://github.com/twentyhq/core-team-issues/issues/696)

- `useAction` hooks have been removed for all actions
- Every action can now declare a react component
- Some standard action components have been introduced: `Action`,
`ActionLink` and `ActionModal`
- The `ActionDisplay` component uses the new `displayType` prop of the
`ActionMenuContext` to render the right component for the action
according to its container: `ActionButton`, `ActionDropdownItem` or
`ActionListItem`
- The `ActionDisplayer` wraps the action component inside a context
which gives it all the information about the action
-`actionMenuEntriesComponenState` has been removed and now all actions
are computed directly using `useRegisteredAction`
- This computation is done inside `ActionMenuContextProvider` and the
actions are passed inside a context
- `actionMenuType` gives information about the container of the action,
so the action can know wether or not to close this container upon
execution
2025-04-09 13:12:49 +00:00
Lucas BordeauandGitHub 1834b38d04 Fix show page relation record count (#11459)
This PR fixes the incorrect relation count on a show page relation
section title, when there are more than 60 records.

An aggregate COUNT query has been used to rely on the backend.

A new component RecordDetailRelationSectionDropdown has been created to
abstract a chunk of the parent RecordDetailRelationSection component.

Fixes https://github.com/twentyhq/twenty/issues/11032
2025-04-09 14:41:11 +02:00
nitinandGitHub bd3ec6d5e3 rename core-module environment to twenty-config (#11445)
closes https://github.com/twentyhq/core-team-issues/issues/759
2025-04-09 14:11:26 +02:00
MarieandGitHub fe6d0241a8 [permissions] Allow logo update during sign-up (#11468)
Fixes https://github.com/twentyhq/twenty/issues/11410
2025-04-09 13:58:30 +02:00
c6203d8928 i18n - translations (#11469)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-09 11:34:35 +02:00
8582bcccf5 remove billing stripe plan product id from env (#11461)
Fixes https://github.com/twentyhq/core-team-issues/issues/661
remove billing stripe plan product id from env

Co-authored-by: Keshav Gupta <keshavgupta@Keshavs-MacBook-Air.local>
2025-04-09 11:31:38 +02:00
EtienneandGitHub 11fb8e0284 add metered products usage (#11452)
- add metered products usage module on settings/billing page
- add new resolver + logic with meter event data fetching from Stripe

<img width="590" alt="Screenshot 2025-04-08 at 16 34 07"
src="https://github.com/user-attachments/assets/34327af1-3482-4d61-91a6-e2dbaeb017ab"
/>
<img width="570" alt="Screenshot 2025-04-08 at 16 31 58"
src="https://github.com/user-attachments/assets/55aa221a-925f-48bf-88c4-f20713c79962"
/>

- bonus : disable subscription switch from yearly to monthly

closes https://github.com/twentyhq/core-team-issues/issues/681
2025-04-09 09:26:49 +00:00
Thomas des FrancsandGitHub b25ee28c12 Update CONTRIBUTING.md (#11465)
Updated the issue assignment policy for good first issues to prioritize
PRs over Issue assignments.
2025-04-09 11:16:13 +02:00
Thomas TrompetteandGitHub 46bbf02431 Emit event on message creation (#11466)
adding event emitting on message creation
2025-04-09 11:04:43 +02:00
GuillimandGitHub c6be260fec datasource TTL fix (#11444)
Comparing the last date a datasource was used instead of a fixed TTL :
should fix workers issues "error: Error: Connection terminated"

FYI was done in pair prog with @Weiko
2025-04-09 10:08:20 +02:00
ccdc2835a2 i18n - translations (#11463)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-09 01:20:17 +02:00
b6e344e7be Various fixes (#11448)
# Scrollbar fix

Fixes https://github.com/twentyhq/twenty/issues/11403

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/b13fe0f2-8c61-4ea8-9ea1-e61e571a90da"
/>

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-04-09 01:03:43 +02:00
ab63214efa Added Proper theme color for Favorite Input box (#11434)
#11418  The background color changes based on the theme.
 - If the theme is 'light', the background color will be white.
- Otherwise, it will use the theme's background transparent lighter
color.

---------

Co-authored-by: ehconitin <nitinkoche03@gmail.com>
Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
2025-04-08 20:46:36 +00:00
martmullandGitHub f121c94d4a 701 workflow improve webhook triggers (#11455)
as title

Nota bene: I did not filter execution by http method. A POST webhook
trigger can be triggered by a GET request for more flexibility. Tell me
if you think it is a mistake


https://github.com/user-attachments/assets/1833cbea-51a8-4772-bcd8-088d6a087e79
2025-04-08 19:01:22 +00:00
2f7f28a574 i18n - translations (#11457)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-08 18:37:10 +02:00
Baptiste DevessierandGitHub 6521d19238 Use JSON visualizer for JSON fields (#11428)
- Updates on the JSON field input
  - Previously, we were editing json fields in a textarea 
- Now, we display a JSON visualizer and the user can click on an Edit
button to edit the JSON in Monaco
- The JSON field input has a special behavior for workflow run output.
We want the error to be displayed first in the visualizer. Displaying
the error in red was optional but makes the output clearer in the
context of a workflow run record board.
- Made the code editor transparent in the json field input
- Ensure workflow run's output is not considered readonly in
`packages/twenty-front/src/modules/object-record/record-field/utils/isFieldValueReadOnly.ts`;
we want the json visualizer to always be displayed in this specific case

## Demo

### Failed Workflow Run


https://github.com/user-attachments/assets/7a438d11-53fb-4425-a982-25bbea4ee7a8

### Any JSON field in the record table


https://github.com/user-attachments/assets/b5591abe-3483-4473-bd87-062a45e653e3

Closes https://github.com/twentyhq/core-team-issues/issues/539
2025-04-08 16:18:36 +00:00
EtienneandGitHub c1d421de06 remove default meter driver (#11456)
Remove default meter driver to prevent metric logs from polluting the
console.
2025-04-08 18:17:58 +02:00
Thomas TrompetteandGitHub dd1d9c32c3 Remove task, note and file tabs for workflows (#11453)
Command menu tries to fetch task, file and notes that are not available
for workflow entities. Hiding those tabs
2025-04-08 17:35:41 +02:00
Thomas TrompetteandGitHub a049cd4a25 Update placeholder on record picker object type update (#11451)
- requires a refacto so several fields can be updated at once
- updating object name on record picker will now update placeholder
- add a min-height to label so fields do not get moved when the label is
deleted
2025-04-08 14:20:15 +00:00
6611fbf9ac Fix : Menu shouldn't be displayed on logged out pages (#11437)
#11414 
Conditionally render MobileNavigationBar based on user authentication
status
- Added useIsLogged hook to check if the user is authenticated.
- Updated MobileNavigationBar component to render only when the user is
logged in.
![Screenshot from 2025-04-08
12-33-04](https://github.com/user-attachments/assets/1b58a5ac-e5ff-418f-a903-b952f37db84d)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-08 11:54:21 +02:00
Charles BochetandGitHub 17474a0e1e Remove cell hotkey scope (#11435)
Remove FieldContext hotkey scope as:
- each Field should set its own hotkey scope (ex:
emails-field-input-{recordId} or emails-field-input for now)
- while opening a fieldInput, we should synchronously set the
corresponding hotkey scope

To cut this refactoring in half, I'm allowing all input to use
TableHotkeyScope.CellEditMode
2025-04-08 11:18:23 +02:00
3d90eb4eb9 Fix broken dropdown auto resize behavior (#11423)
This PR was originally about fixing advanced filter dropdown auto resize
to avoid breaking the app main container, but the regression is not
limited to advanced filter dropdown, so this PR fixes the regression for
every dropdown in the app.

This PR adds a max dropdown max width to allow resizing dropdowns
horizontally also, which can happen easily for the advanced filter
dropdown.

In this PR we also start removing `fieldMetadataItemUsedInDropdown` in
component `AdvancedFilterDropdownTextInput` because it has no impact
outside of this component which is used only once.

The autoresize behavior determines the right padding-bottom between
mobile and PC.

Mobile : 

<img width="604" alt="Capture d’écran 2025-04-07 à 16 03 12"
src="https://github.com/user-attachments/assets/fbdd8020-1bfc-4e01-8a05-3a9f114cdd40"
/>

PC :

<img width="757" alt="Capture d’écran 2025-04-07 à 16 03 30"
src="https://github.com/user-attachments/assets/f80a5967-8f60-40bb-ae3c-fa9eb4c65707"
/>

Fixes https://github.com/twentyhq/core-team-issues/issues/725
Fixes https://github.com/twentyhq/twenty/issues/11409

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-08 11:03:10 +02:00
Félix MalfaitandGitHub 89abf3db4f Remove dead code to backfill record positions (#11439)
Fixes https://github.com/twentyhq/core-team-issues/issues/767
2025-04-08 11:02:40 +02:00
8b5c259c36 i18n - translations (#11441)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-08 11:01:29 +02:00
ea93ac6348 fetch latest version tag from docker hub (#11362)
closes #11352

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-08 08:55:03 +00:00
eliasylonenandGitHub 95eba07f6e Share RICH_TEXT_V2 field value override between REST and GraphQL APIs (#10912)
Fixes issue #10606.

This PR makes `RICH_TEXT_V2` field behavior in REST API matche the
current behavior in GraphQL API:

Currently both `markdown` and `blocknote` fields must be included in the
request, one of them can be `null`. The field with a `null` value will
be filled by the converted value of the other field.

In other words, this works:
```
curl http://localhost:3000/rest/notes \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC0xYzI1LTRkMDItYmYyNS02YWVjY2Y3ZWE0MTkiLCJ0eXBlIjoiQVBJX0tFWSIsIndvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWMyNS00ZDAyLWJmMjUtNmFlY2NmN2VhNDE5IiwiaWF0IjoxNzQxODA1MzQyLCJleHAiOjQ4OTU0MDUzNDEsImp0aSI6ImZlMzU0NTBkLTlhMDMtNGE2ZS04ODVjLTBlNTU3M2Y3YTE0NiJ9.6_g8cwoSE7ZCX1Zzsw44gZIyBdLKNsnDqMOmm1bKik0' \
  --data '{
  "position": 1,
  "title": "a",
  "bodyV2": {    
    "markdown": "test4\n\ntest3\n\n# test1\n",
    "blocknote": null
  },
  "createdBy": {
    "source": "EMAIL"
  }
}'
```

And this does not work:
```
curl http://localhost:3000/rest/notes \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC0xYzI1LTRkMDItYmYyNS02YWVjY2Y3ZWE0MTkiLCJ0eXBlIjoiQVBJX0tFWSIsIndvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWMyNS00ZDAyLWJmMjUtNmFlY2NmN2VhNDE5IiwiaWF0IjoxNzQxODA1MzQyLCJleHAiOjQ4OTU0MDUzNDEsImp0aSI6ImZlMzU0NTBkLTlhMDMtNGE2ZS04ODVjLTBlNTU3M2Y3YTE0NiJ9.6_g8cwoSE7ZCX1Zzsw44gZIyBdLKNsnDqMOmm1bKik0' \
  --data '{
  "position": 1,
  "title": "",
  "body": "",
  "bodyV2": {    
    "markdown": "test4\n\ntest3\n\n# test1\n"
  },
  "createdBy": {
    "source": "EMAIL"
  }
}'
```

---

It would be nice not to require the null value, maybe let's make that a
separate PR?
2025-04-07 23:30:53 +02:00
6bc18960c9 Show Header in RecordTable on empty state and show groups in Group By views (#11416)
Closes #11298

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-07 22:05:59 +02:00
07b25a2aad i18n - translations (#11432)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-07 19:33:05 +02:00
Charles BochetandGitHub 20895f1129 Fix views reordering (#11431)
As per title
2025-04-07 19:18:05 +02:00
Thomas TrompetteandGitHub 17b7e703b4 Refacto form select input (#11426)
- small fixes on form design
- refacto form select input to use the existing select component
2025-04-07 16:56:59 +00:00
WeikoandGitHub ff59658d39 Fix permission check during onboarding (#11429)
## Context
CurrentUser is fetched during onboarding however roles and permissions
are not created yet during that stage so an error was thrown. We only
want to fetch permissions after the onboarding of the workspace.
2025-04-07 18:53:53 +02:00
WeikoandGitHub f403c551d7 Add settings permissions check on FE (#11425)
## Context
Now that we can update role settings permissions, we need to reflect
that on the FE as well (hiding/showing nav items + redirection logic).
Feature flag check here is not really needed because since not having
any setting permission will result in the same behavior as Permission
V1.
This PR updates the resolvers to return settings permissions of the
current user
2025-04-07 17:15:33 +02:00
Charles Bochet d4db399933 Fix Google Icon 2025-04-07 17:14:36 +02:00
0226dec717 i18n - translations (#11427)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-07 17:13:37 +02:00
GuillimandGitHub 6451b7b5e3 Fix-messaging-calendar-issues (#11424)
- fixing Event Calendar bug due to TypeORM limitations
- avoid systematic crash on contact creation jobs, simply logging
2025-04-07 17:13:13 +02:00
Paul RastoinandGitHub 69da046812 Twenty-website copy twenty-ui dockerfile (#11394)
Fixes deployment


https://github-production-user-asset-6210df.s3.amazonaws.com/45004772/430425195-218d6f61-3ab0-4042-8206-52eac22fe599.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAVCODYLSA53PQK4ZA%2F20250404%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250404T143735Z&X-Amz-Expires=300&X-Amz-Signature=489088bc5bf23c371d80d655c83a61e8ba481313b368369785c203b7268dd924&X-Amz-SignedHeaders=host
2025-04-07 17:09:55 +02:00
GuillimandGitHub c798cccba7 Switching plan overflows (#11396)
Swithcing plan overflows the modal soo Bonapara said to go back to
simple switch plan until we have a better version next week with the
stirpe pricing page
2025-04-07 17:09:29 +02:00
Charles BochetandGitHub 59ae978ee3 Fix safari broken table (#11417)
In this PR:
- deprecate usage of useInView (react-intersection-observer) for record
table
- fixes #11254
2025-04-07 16:33:02 +02:00
26504f02a3 i18n - translations (#11422)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-07 15:39:19 +02:00
EtienneandGitHub 361b7682dd add trial period ending banner + server logic (#11389)
Solution : 
- if user reaches his workflow usage cap + in trial period > display
banner
- end trial period if user has payment method (if not, not possible)

<img width="941" alt="Screenshot 2025-04-04 at 10 27 32"
src="https://github.com/user-attachments/assets/d7a1d5f7-9b12-4a92-a7c7-15ef8847c790"
/>
2025-04-07 15:28:02 +02:00
nitinandGitHub a627eff5c2 fix: Use namePlural instead of labelPlural for favorite view URLs (#11407)
closes #11404

Used `namePlural` instead of `labelPlural` for generating favorite view
URLs to ensure proper routing across all languages.
2025-04-07 08:54:43 +02:00
Lucas BordeauandGitHub f365caa365 Fixed ViewBarDetails unnecessary padding-top (#11395)
This PR fixes a recent change in ViewBarDetails that added an
unnecessary padding-top.

Before : 

<img width="876" alt="image"
src="https://github.com/user-attachments/assets/f0152f24-da2c-44f7-b299-a98cb559b2d1"
/>

After : 

<img width="884" alt="image"
src="https://github.com/user-attachments/assets/48a0c9d8-1c22-4eb7-abfa-02963facbcd6"
/>
2025-04-07 07:37:19 +02:00
Charles BochetandGitHub 8fa09e21ec Fix safari broken table (#11399)
Fixes #11254
2025-04-04 19:16:33 +02:00
241d8820d7 i18n - translations (#11398)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-04 17:47:01 +02:00
WeikoandGitHub e1f6c61651 add settings permissions update (#11377)
Fixes https://github.com/twentyhq/core-team-issues/issues/710
2025-04-04 17:40:14 +02:00
6142e193ce i18n - translations (#11397)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-04 17:34:18 +02:00
10e140495c Fixing Singup sequence FLASHING💥 (#11371)
After investiagting the different options ([see related
issue](https://github.com/twentyhq/core-team-issues/issues/660#issuecomment-2766030972))
I decided to add a "Verify Component" and a to build a custom Layout for
this route.

Reason I cannot use the default one is to have all preloaded once the
user changes website and lands on the verify route.

Reason I did not modify the DefaultLayout to match our need is that is
would require many changes in order to avoid preloading states for our
specific usecase.

Fixes https://github.com/twentyhq/core-team-issues/issues/660

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-04-04 15:25:15 +00:00
Charles Bochet 609e06fd14 Fix main build 2025-04-04 16:21:23 +02:00
2308091b13 Remove overlay-scroll-bar (#11258)
## What

- Deprecate overlayscrollbars as we decided to follow the native
behavior
- rework on performances (avoid calling recoil states too much at field
level which is quite expensive)
- Also implements:
https://github.com/twentyhq/core-team-issues/issues/569

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-04 16:13:48 +02:00
Thomas TrompetteandGitHub 6b184cc641 Select node by default when pending form action (#11378)
We want the run side panel to be open when the form step is pending



https://github.com/user-attachments/assets/a7a7015e-b0b7-422a-b625-eca8f2614ac1
2025-04-04 15:56:57 +02:00
Lucas BordeauandGitHub 59e8e0633b Fix advanced filter dropdown input components (#11381)
This PR fixes the filter value input components that are used in
advanced dropdown filter, which slightly differ from the classic object
filter dropdown in the view bar.

We notably needed the same experience as other text inputs in the
application, for entering filter values.

## New text and number filter experience : 

<img width="681" alt="image"
src="https://github.com/user-attachments/assets/b373bb6b-dc00-4396-9294-9b866b91fa02"
/>

## New date filter experience : 

<img width="683" alt="image"
src="https://github.com/user-attachments/assets/8aea22e2-6f3b-4641-9f3d-6d7ba537bc27"
/>

To obtain the same experience for date input as in workflow forms, it
would require to duplicate or factorize a lot of complex code that
manipulates dates and user events with the input, it would be better
tackled in another issue related to a larger refactor effort :
https://github.com/twentyhq/core-team-issues/issues/736

Fixes https://github.com/twentyhq/core-team-issues/issues/674
2025-04-04 12:45:21 +00:00
Raphaël BosiandGitHub ad2357a6fd Fix error when workflows aren't enabled (#11388)
Fix Uncaught Error: Workflow is not enabled. If you want to use it,
please enable it in the lab.
<img width="505" alt="erroractionmenu"
src="https://github.com/user-attachments/assets/66e60219-20fb-4b00-90e4-d6bd640be774"
/>

This error was due to using the hook `useWorkflowWithCurrentVersion`
outside of a workflow object. Adding a skip parameter wasn't enough
because the `useFindOneRecord` uses `useObjectMetadataItem` which throws
if workflows aren't enabled.
2025-04-04 14:26:19 +02:00
27256c960e i18n - translations (#11387)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-04 11:33:11 +02:00
Baptiste DevessierandGitHub 9353e777ea Copy JSON values on click (#11382)
https://github.com/user-attachments/assets/1638c196-fb9c-4f2b-910c-6d8b0693a37a

Closes https://github.com/twentyhq/core-team-issues/issues/568
2025-04-04 11:20:57 +02:00
WeikoandGitHub bb40bc9929 Fix update field default value (#11386)
Fixes https://github.com/twentyhq/twenty/issues/11379
2025-04-04 08:58:53 +00:00
Lucas BordeauGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix Malfait
5e43839efb Fix CSV import select field matching (#11361)
This PR fixes a bug that prevented to do the matching of an imported CSV
file that contains a SELECT type column.

Fixes https://github.com/twentyhq/twenty/issues/11220

## Stacking context improvement 

During the development it was clear that we lacked a reliable way to
understand our own z indices for components like modal, portaled
dropdown, overlay background, etc.

So in this PR we introduce a new enum RootStackingContextZIndices, this
enum allows to keep track of our root stacking context component
z-index, and because it is an enum, it prevents any conflict.

See
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Stacking_context
for reference.

## Component cleaning

Components have been reorganized in a SubMatchingSelectRow component

The Dropdown component has been used to replace the SelectInput
component which doesn't fit this use case because we are not in a cell,
we just need a simple standalone dropdown, though it would be
interesting to extract the UI part of the SelectInput, to share it here,
the benefit is not obvious since we already have good shared components
like Tag and Dropdown to implement this specific use case.

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-03 16:28:15 +02:00
EtienneandGitHub 752eb93836 disable workflow execution if billing issue (#11374)
closes https://github.com/twentyhq/core-team-issues/issues/404
2025-04-03 14:18:44 +00:00
7eec64b6e0 have footer on emails (#11300)
# ISSUE 

- Closes #9622

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-03 14:26:19 +02:00
EtienneandGitHub cfae440a02 add stripe alert listening and cap on subscriptionItems (#11330)
in this PR :  
- reverting https://github.com/twentyhq/twenty/pull/11319 > at trial
period end, subscriptions switch to 'past_due' status if payment method
not set up
- adding cap on subscriptionItems and updating them when receiving alert
event + refreshing them when beginning a new subscription cycle

closes https://github.com/twentyhq/core-team-issues/issues/606
2025-04-03 13:44:32 +02:00
Baptiste DevessierandGitHub 144a326709 JSON visualizer: Highlight the parent nodes of in-use nodes (#11373)
https://github.com/user-attachments/assets/5f31023d-b24f-40c8-a061-ffc0d02b63b0

Closes https://github.com/twentyhq/core-team-issues/issues/715
2025-04-03 12:11:19 +02:00
Paul RastoinandGitHub 4a4e65fe4a [REFACTOR] Twenty UI multi barrel (#11301)
# Introduction
closes https://github.com/twentyhq/core-team-issues/issues/591
Same than for `twenty-shared` made in
https://github.com/twentyhq/twenty/pull/11083.

## TODO
- [x] Manual migrate twenty-website twenty-ui imports

## What's next:
- Generate barrel and migration script factorization within own package
+ tests
- Refactoring using preconstruct ? TimeBox
- Lint circular dependencies
- Lint import from barrel and forbid them

### Preconstruct
We need custom rollup plugins addition, but preconstruct does not expose
its rollup configuration. It might be possible to handle this using the
babel overrides. But was a big tunnel.
We could give it a try afterwards ! ( allowing cjs interop and stuff
like that )
Stuck to vite lib app

Closed related PRs:
- https://github.com/twentyhq/twenty/pull/11294
- https://github.com/twentyhq/twenty/pull/11203
2025-04-03 09:47:55 +00:00
MarieandGitHub 8c9fcfe5a4 Hot fix for currentWorkspaceMember not found error on blocklist page (#11367)
Fixes
https://twenty-v7.sentry.io/issues/6504066204/?project=4507072563183616
Introduced by https://github.com/twentyhq/twenty/pull/11325

Called it a hotfix as not sure if missing currentWorkspaceMember is an
expected state - maybe it is expected to be temporarily missing ?
2025-04-03 08:44:11 +00:00
MarieandGitHub 0df07a766a Handle no value options in filters (#11351)
Fixes #11323 - see description to reproduce

The issue was that the filter was malformed for no value options: 
<img width="649" alt="Capture d’écran 2025-04-02 à 14 56 25"
src="https://github.com/user-attachments/assets/5287c4f8-7eaf-4488-b692-4d7634236d3d"
/>
causing
<img width="333" alt="Capture d’écran 2025-04-02 à 14 56 43"
src="https://github.com/user-attachments/assets/aa1b7333-50da-4b7d-979b-70dab9a1ab41"
/>


after fix: 
<img width="653" alt="Capture d’écran 2025-04-02 à 14 39 56"
src="https://github.com/user-attachments/assets/1777c068-7231-4e14-bc41-84ef7909cf10"
/>
2025-04-03 10:41:50 +02:00
Thomas TrompetteandGitHub 256a5c1a2b Remove form feature flag (#11369)
As title. Workflows are still in the lab and forms are starting to be
usable
2025-04-03 08:38:19 +00:00
Raphaël BosiandGitHub 1240d39f56 Introduce hooks to retrieve directly the registered actions without using actionMenuEntriesComponentState (#11359)
Introduce two hooks:
- `useRegisteredRecordActions`
- `useRegisteredRecordAgnosticActions`

These hooks will be used to read directly the registered actions
according to the context.
We will stop to rely on `actionMenuEntriesComponentState` to improve
performances and reduce state copies and updates.

This PR is part of
https://github.com/twentyhq/core-team-issues/issues/683, and at this
step, we still save the actions inside
`actionMenuEntriesComponentState`.
2025-04-03 10:25:42 +02:00
Thomas TrompetteandGitHub a062a17229 Add form date field (#11360)
Builder
<img width="498" alt="Capture d’écran 2025-04-02 à 19 02 20"
src="https://github.com/user-attachments/assets/29db9fa9-aae4-4d1f-98f2-0b2371f944f1"
/>

Execution
<img width="837" alt="Capture d’écran 2025-04-02 à 19 02 47"
src="https://github.com/user-attachments/assets/ce1c442c-3c06-4f7e-99d6-3eb8fb1d2428"
/>
2025-04-03 10:10:43 +02:00
GuillimandGitHub 8abec309e0 Phone-onclickoutside (#11350)
Fixes : For phones I have to press "enter" to validate my changes but
for other fields it's saved automatically when I leave the cell

Bug related to onClickOutside on the MultiItemFieldMenuItem component
that shows phones (but also emails...)

Seen with @bonapara : we keep a consitent behaviour meaning
- saving input on click outside when primary item is being edited
- not saving input on click outside when other items are being edited



Fixes https://github.com/twentyhq/twenty/issues/11246
2025-04-03 07:57:02 +00:00
Baptiste DevessierandGitHub bea75b9532 Set failed node's output as red (#11358)
| Error | Success |
|--------|--------|
| ![CleanShot 2025-04-02 at 18 18
45@2x](https://github.com/user-attachments/assets/6674d4d2-344a-4e16-9608-a70cde07a376)
| ![CleanShot 2025-04-02 at 18 20
23@2x](https://github.com/user-attachments/assets/55b5a467-528f-4f07-9166-40ed14943ee2)
|

Closes https://github.com/twentyhq/core-team-issues/issues/716
2025-04-03 08:58:56 +02:00
183dc40916 [FIX] Out of memory while running app localy (#11341)
# Introduction
Lately encountering a lot of out of memory error when running
twenty-front in watch mode with both TypeScript and lint checkers
```ts
Error: Worker terminated due to reaching memory limit: JS heap out of memory
    at new NodeError (node:internal/errors:405:5)
    at [kOnExit] (node:internal/worker:287:26)
    at Worker.<computed>.onexit (node:internal/worker:209:20)
```

The existing configuration looks like this:
```ts
// packages/twenty-front/vite.config.ts
'cd ../.. && eslint packages/twenty-front --report-unused-disable-directives --max-warnings 0 --config .eslintrc.cjs',
```
This is wrong as computing the root eslintrc completely omitting
twenty-front's one ***and its ignorePattern*** so will be checking in
`node_modules` etc checking for project-structure :).
For example this a
[snippet](https://gist.github.com/prastoin/d7f8ad4ef5eb2f7732209b756a38094c)
of the above commands errors. We can see rule that should be disabled by
`eslintrc.react.cjs` extension made from twenty-front `eslintrc` :
```ts
/Users/paulrastoin/ws/twenty-two/packages/twenty-front/src/modules/settings/data-model/fields/forms/components/__stories__/SettingsDataModelFieldSettingsFormCard.stories.tsx
  23:27  warning  Forbidden non-null assertion  @typescript-eslint/no-non-null-assertion
```

## Fixes
- consume the `twenty-front` package eslint configuration within the
vite lint checker
- eslint overrides extends are getting merged based on glob inclusion of
their files declarations
- any linted files should be included in one of our `tsconfig`
- removed redundant and counter-productive negative `ignorePatterns`, as
eslint will naturally only lint files within configuration file
directory by default which will result making it go through local
`node_modules` project structure

## Now
Less cpu usage <3.5 gb and faster
```ts
// from packages/twenty-front
TIMING=1  npx eslint . --report-unused-disable-directives --max-warnings 0 --config .eslintrc.cjs --debug
#...
Rule                                            | Time (ms) | Relative
:-----------------------------------------------|----------:|--------:
project-structure/folder-structure              | 19578.927 |    20.2%
prettier/prettier                               | 13746.156 |    14.2%
no-redeclare                                    |  9546.570 |     9.9%
@nx/workspace-explicit-boolean-predicates-in-if |  8167.805 |     8.4%
@typescript-eslint/no-unused-vars               |  6872.803 |     7.1%
import/no-relative-packages                     |  6577.273 |     6.8%
@nx/enforce-module-boundaries                   |  6520.945 |     6.7%
import/no-duplicates                            |  4987.476 |     5.2%
react/no-direct-mutation-state                  |  2323.082 |     2.4%
react/require-render-return                     |  1155.261 |     1.2%
```

## Conclusion
Please note that `nx linter` might not be as strict as vite config
eslint runner

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-04-02 18:35:00 +02:00
010b7663c4 i18n - translations (#11357)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-02 18:21:16 +02:00
Raphaël BosiandGitHub 5e905180c8 690 extract shouldberegistered from the useaction hooks (#11355)
Closes https://github.com/twentyhq/core-team-issues/issues/690

This PR is the first part of a refactoring on the actions system
https://github.com/twentyhq/core-team-issues/issues/683. It:
- Removes `shouldBeRegistered` from the useAction hook
- Instead `shouldBeRegistered` becomes a function to which we can pass
parameters which describe the context of the app (the object, the
selected record, information about favorites ...). It returns a boolean.
- `useShouldActionBeRegisteredParams` returns the parameters to pass to
the `shouldBeRegistered`
- Introduces a way to inherit actions from the default config and to
overwrite its properties, closing
https://github.com/twentyhq/core-team-issues/issues/72

Some tests testing if an action was registered correctly have been
removed, we should add them back at the end of the global refactoring.
2025-04-02 17:58:14 +02:00
Antoine MoreauxandGitHub bc57e98949 chore(ci): extend timeout for Danger JS job (#11356)
Increased the timeout for the Danger JS job from 3 to 5 minutes to
prevent premature failures on slower runs. This ensures more reliable
execution of the workflow.

To unlock https://github.com/twentyhq/twenty/pull/11339
2025-04-02 17:26:52 +02:00
Thomas TrompetteandGitHub 7488c6727a Add record picker in form action (#11331)
Record picker becomes a form field that could be used in another context
than workflows.

Settings
<img width="488" alt="Capture d’écran 2025-04-02 à 10 55 53"
src="https://github.com/user-attachments/assets/a9fc09ff-28cd-4ede-8aaa-af1e986cda8e"
/>

Execution
<img width="936" alt="Capture d’écran 2025-04-02 à 10 57 36"
src="https://github.com/user-attachments/assets/d796aeeb-cae1-4e59-b388-5b8d08739ea8"
/>
2025-04-02 17:08:33 +02:00
EtienneandGitHub 2bc9691021 fix stripe subscription deletion (#11353)
when soft deleting workspace, stripe subscription is canceled then
workspace is soft deleted before stripe async web hook event is
received. This webhook event is needed to update billingSubscription
status.
2025-04-02 15:59:09 +02:00
2b14cd5649 i18n - translations (#11354)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-04-02 15:47:16 +02:00
c03438a02e Support Moved to Security Setting (#11335)
This PR addresses issue #11321 by moving the "Support" section from the
General tab to the Security tab.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-04-02 13:40:56 +00:00
Félix MalfaitandGitHub e94065fb44 Auto-run migration script on docker entrypoint (#11338)
A small PR but a big step towards making Twenty easier to self-host and
upgrade!

Now changing the tag and pulling a new version should be the only step
to upgrade as migrations script will be ran automatically upon starting
the containers. It was already the case for typeorm migrations, but not
for standard objects migration and data migration scripts. It is still
possible to disable this behavior for the most complex deployments such
as our own cloud.
2025-04-02 15:37:51 +02:00
martmullandGitHub 55eadf1ab4 11312 rest api cant filter enum type columns by null value (#11343)
- Fixes https://github.com/twentyhq/twenty/issues/11312
- Fixes record undefined on webhook deleted events
- Emit destroy event when deleting record via the rest api
2025-04-02 15:07:53 +02:00
Paul RastoinandGitHub 76bbffc315 [FIX] Upgrade command missmatch (#11348)
# Introduction
As we deploy patch from the main branch we've ship the upgrade for the
`0.51` within the `0.50`.
We should only do that when about to release

We should find a way for this not to occur again
2025-04-02 11:58:50 +00:00
EtienneandGitHub da1413c5a1 fix hot reload (#11347) 2025-04-02 11:42:05 +00:00
martmullandGitHub c6afb0d1ba Revert "[4/n]: migrate the RESTAPI GET /rest/* to use TwentyORM direc… (#11344)
…tly (#10372)"

This reverts commit a26b3f54d6.
2025-04-02 13:39:28 +02:00
Lucas BordeauandGitHub e47c19e86f Advanced filter bug bash (#11327)
This PR fixes some bugs on advanced filters dropdown.

See reference master issue :
https://github.com/twentyhq/core-team-issues/issues/648

Fixes https://github.com/twentyhq/core-team-issues/issues/726
Fixes https://github.com/twentyhq/core-team-issues/issues/724
Fixes https://github.com/twentyhq/core-team-issues/issues/655
2025-04-02 10:25:51 +02:00
martmullandGitHub 6e92b19e01 11311 object create webhook should be triggered when object is created via rest api (#11336)
Fixes https://github.com/twentyhq/twenty/issues/11311
2025-04-02 10:22:22 +02:00
GauravandGitHub 9a2f7d8b71 Fix: Timeline responsiveness (#11288)
Fixes #11136


[recording.webm](https://github.com/user-attachments/assets/328afab8-511a-4090-bdb0-e1cdb42565be)
2025-04-02 10:07:05 +02:00
Antoine MoreauxandGitHub 44bf393b06 fix(email-validation): validation email cross workspace (#11261)
- Finish removing captcha guard from validation  email
- Fix an issue where domain validation wasn't working on a multi-domain
setup
2025-04-02 08:06:34 +00:00
44d4e4efaf fix: Display multipicker on Created By source filter (#10543)
fix: #9674 

When the selected filter is Is and the field type is ACTOR, we now show
ObjectFilterDropdownSourceSelect instead of a text input. This ensures
proper selection for actor-based filters. Also previously, when a user
changed the selected option, all default values were getting wiped out
so i have made some changes in updatedSelectedItems

Loom video:
https://www.loom.com/share/8b80a78d5e8c4a5192d69cab96f0c838?sid=5bd76fff-7cd4-4e3c-8c48-d1c9e4e95651

---------

Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: prastoin <paul@twenty.com>
Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-02 09:56:32 +02:00
WeikoandGitHub 3357f93415 Bump 0.51.0-canary (#11329) 2025-04-02 09:23:17 +02:00
15837 changed files with 1265591 additions and 323101 deletions
+18
View File
@@ -0,0 +1,18 @@
{
"install": "curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash - && sudo apt-get install -y nodejs && node --version && yarn install && echo 'Setting up Docker Compose environment...' && cd packages/twenty-docker && cp -n docker-compose.yml docker-compose.dev.yml || true && echo 'Dependencies installed and docker-compose prepared'",
"start": "sudo service docker start && echo 'Docker service started' && cd packages/twenty-docker && echo 'Installing yq for YAML processing...' && sudo apt-get update -qq && sudo apt-get install -y wget && wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 && sudo chmod +x /usr/local/bin/yq && echo 'Patching docker-compose for local development...' && yq eval 'del(.services.server.image)' -i docker-compose.dev.yml && yq eval '.services.server.build.context = \"../../\"' -i docker-compose.dev.yml && yq eval '.services.server.build.dockerfile = \"./packages/twenty-docker/twenty/Dockerfile\"' -i docker-compose.dev.yml && yq eval 'del(.services.worker.image)' -i docker-compose.dev.yml && yq eval '.services.worker.build.context = \"../../\"' -i docker-compose.dev.yml && yq eval '.services.worker.build.dockerfile = \"./packages/twenty-docker/twenty/Dockerfile\"' -i docker-compose.dev.yml && echo 'Setting up .env file with database configuration...' && echo 'SERVER_URL=http://localhost:3000' > .env && echo 'APP_SECRET='$(openssl rand -base64 32) >> .env && echo 'PG_DATABASE_PASSWORD='$(openssl rand -hex 16) >> .env && echo 'PG_DATABASE_URL=postgres://postgres:password@localhost:5432/postgres' >> .env && echo 'SIGN_IN_PREFILLED=true' >> .env && echo 'Building and starting services...' && docker-compose -f docker-compose.dev.yml up -d --build && echo 'Waiting for services to initialize...' && sleep 30 && echo 'Checking service health...' && docker-compose -f docker-compose.dev.yml ps && echo 'Environment setup complete!'",
"terminals": [
{
"name": "Database Setup & Seed",
"command": "sleep 40 && cd packages/twenty-docker && echo 'Waiting for PostgreSQL to be ready...' && until docker-compose -f docker-compose.dev.yml exec -T db pg_isready -U postgres; do echo 'Waiting for PostgreSQL...'; sleep 5; done && echo 'PostgreSQL is ready!' && echo 'Waiting for Twenty server to be healthy...' && until docker-compose -f docker-compose.dev.yml exec -T server curl --fail http://localhost:3000/healthz 2>/dev/null; do echo 'Waiting for server...'; sleep 5; done && echo 'Server is healthy!' && echo 'Running database setup and seeding...' && docker-compose -f docker-compose.dev.yml exec -T server npx nx database:reset twenty-server && echo 'Database seeded successfully!' && bash"
},
{
"name": "Application Logs",
"command": "sleep 35 && cd packages/twenty-docker && echo 'Following application logs...' && docker-compose -f docker-compose.dev.yml logs -f server worker"
},
{
"name": "Service Monitor",
"command": "sleep 15 && cd packages/twenty-docker && echo '=== Service Status Monitor ===' && while true; do clear; echo '=== Service Status at $(date) ===' && docker-compose -f docker-compose.dev.yml ps && echo '\\n=== Health Status ===' && (docker-compose -f docker-compose.dev.yml exec -T server curl -s http://localhost:3000/healthz 2>/dev/null && echo '✅ Twenty Server: Healthy') || echo '❌ Twenty Server: Not Ready' && (docker-compose -f docker-compose.dev.yml exec -T db pg_isready -U postgres 2>/dev/null && echo '✅ PostgreSQL: Ready') || echo '❌ PostgreSQL: Not Ready' && echo '\\n=== Database Connection Test ===' && docker-compose -f docker-compose.dev.yml exec -T server node -e \"const { Client } = require('pg'); const client = new Client({connectionString: process.env.PG_DATABASE_URL}); client.connect().then(() => {console.log('✅ Database Connection: OK'); client.end();}).catch(e => console.log('❌ Database Connection: Failed -', e.message));\" || echo 'Connection test failed' && sleep 45; done"
}
]
}
+18
View File
@@ -0,0 +1,18 @@
{
"install": "curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash - && sudo apt-get install -y nodejs && node --version && yarn install && echo 'Installing dependencies complete'",
"start": "sudo service docker start && echo 'Docker service started' && sleep 3 && echo 'Starting PostgreSQL and Redis containers...' && make postgres-on-docker && make redis-on-docker && echo 'Waiting for containers to initialize...' && sleep 20 && echo 'Checking container status...' && docker ps --filter name=twenty_ && echo 'Waiting for PostgreSQL to be ready...' && until docker exec twenty_pg pg_isready -U postgres -h localhost; do echo 'PostgreSQL not ready yet, waiting...'; sleep 3; done && echo 'PostgreSQL is ready!' && echo 'Setting up database...' && cd packages/twenty-server && npx nx database:reset twenty-server || echo 'Database already initialized' && echo 'Environment setup complete!'",
"terminals": [
{
"name": "Development Server",
"command": "echo 'Waiting for database to be fully ready...' && sleep 30 && until docker exec twenty_pg pg_isready -U postgres -h localhost; do echo 'Waiting for PostgreSQL...'; sleep 2; done && echo 'Starting Twenty development server...' && export SERVER_URL=http://localhost:3000 && export PG_DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres && yarn start"
},
{
"name": "Database Management",
"command": "sleep 25 && echo 'Database management terminal ready' && echo 'Waiting for PostgreSQL to be available...' && until docker exec twenty_pg pg_isready -U postgres -h localhost; do echo 'Waiting for PostgreSQL...'; sleep 2; done && echo 'PostgreSQL is ready for database operations!' && echo 'You can now run database commands like:' && echo ' npx nx database:reset twenty-server' && echo ' npx nx database:migrate twenty-server' && bash"
},
{
"name": "Container Logs & Status",
"command": "sleep 10 && echo '=== Container Status Monitor ===' && while true; do echo '\\n=== Container Status at $(date) ===' && docker ps --filter name=twenty_ --format 'table {{.Names}}\\t{{.Status}}\\t{{.Ports}}' && echo '\\n=== PostgreSQL Status ===' && (docker exec twenty_pg pg_isready -U postgres -h localhost && echo 'PostgreSQL: ✅ Ready') || echo 'PostgreSQL: ❌ Not Ready' && echo '\\n=== Redis Status ===' && (docker exec twenty_redis redis-cli ping && echo 'Redis: ✅ Ready') || echo 'Redis: ❌ Not Ready' && sleep 30; done"
}
]
}
-65
View File
@@ -1,65 +0,0 @@
# Twenty Development Rules
This directory contains Twenty's development guidelines and best practices. The rules are organized into several key categories:
## Guidelines Structure
### 1. Architecture and Structure
- `architecture.md`: Project overview, technology stack, and infrastructure setup
- `file-structure-guidelines.md`: File and directory organization patterns
### 2. Code Style and Development
- `typescript-guidelines.md`: TypeScript best practices and conventions
- `code-style-guidelines.md`: General coding standards and style guide
### 3. React Development
- `react-general-guidelines.md`: Core React development principles and patterns
- `react-state-management-guidelines.md`: State management approaches and best practices
### 4. Testing
- `testing-guidelines.md`: Testing strategies, patterns, and best practices
### 5. Internationalization
- `translations.md`: Translation workflow, i18n setup, and string management
## Common Development Commands
### Frontend Commands
```bash
# Testing
npx nx test twenty-front # Run unit tests
npx nx storybook:build twenty-front # Build Storybook
npx nx storybook:serve-and-test:static # Run Storybook tests
# Development
npx nx lint twenty-front # Run linter
npx nx typecheck twenty-front # Type checking
npx nx run twenty-front:graphql:generate # Generate GraphQL types
```
### Backend Commands
```bash
# Database
npx nx database:reset twenty-server # Reset database
npx nx run twenty-server:database:init:prod # Initialize database
npx nx run twenty-server:database:migrate:prod # Run migrations
# Development
npx nx run twenty-server:start # Start the server
npx nx run twenty-server:lint # Run linter (add --fix to auto-fix)
npx nx run twenty-server:typecheck # Type checking
npx nx run twenty-server:test # Run unit tests
npx nx run twenty-server:test:integration:with-db-reset # Run integration tests
# Migrations
npx nx run twenty-server:typeorm migration:generate src/database/typeorm/metadata/migrations/[name] -d src/database/typeorm/metadata/metadata.datasource.ts
# Workspace
npx nx run twenty-server:command workspace:sync-metadata -f # Sync metadata
```
## Usage
These rules are automatically attached to relevant files in your workspace through Cursor's context system. They help maintain consistency and quality across the Twenty codebase.
For the most up-to-date version of these guidelines, always refer to the files in this directory.
+137
View File
@@ -0,0 +1,137 @@
---
description: Twenty CRM development rules and best practices
globs: []
alwaysApply: true
---
# Twenty Development Rules
This directory contains Twenty's development guidelines and best practices in the modern Cursor Rules format (MDC). These rules are automatically applied based on file patterns and provide context-aware guidance to AI assistants.
## Rules Overview
### Core Guidelines
- **architecture.mdc** - Project overview, technology stack, and infrastructure setup (Always Applied)
- **nx-rules.mdc** - Nx workspace guidelines and best practices (Auto-attached to Nx files)
### Code Quality
- **typescript-guidelines.mdc** - TypeScript best practices and conventions (Auto-attached to .ts/.tsx files)
- **code-style.mdc** - General coding standards and style guide (Auto-attached to code files)
- **file-structure.mdc** - File and directory organization patterns (Auto-attached to config files)
### React Development
- **react-general-guidelines.mdc** - Core React development principles (Auto-attached to React files)
- **react-state-management.mdc** - State management approaches with Recoil (Auto-attached to state files)
### Testing & Quality
- **testing-guidelines.mdc** - Testing strategies and best practices (Auto-attached to test files)
### Internationalization
- **translations.mdc** - Translation workflow and i18n setup (Auto-attached to locale files)
## How Rules Work
### Automatic Attachment
Rules are automatically included in your AI context based on file patterns (globs). When you work on TypeScript files, the TypeScript guidelines are automatically loaded.
### Manual Reference
You can manually reference any rule using the `@ruleName` syntax:
- `@nx-rules` - Include Nx-specific guidance
- `@react-general-guidelines` - Load React best practices
- `@testing-guidelines` - Get testing recommendations
### Rule Types Used
- **Always Applied** - Loaded in every context (architecture.mdc, README.mdc)
- **Auto Attached** - Loaded when matching file patterns are referenced
- **Agent Requested** - Available for AI to include when relevant
- **Manual** - Only included when explicitly mentioned
## Development Commands
### Frontend Commands
```bash
# Testing
npx nx test twenty-front # Run unit tests
npx nx storybook:build twenty-front # Build Storybook
npx nx storybook:serve-and-test:static # Run Storybook tests
# Development
npx nx lint twenty-front # Run linter
npx nx typecheck twenty-front # Type checking
npx nx run twenty-front:graphql:generate # Generate GraphQL types
```
### Backend Commands
```bash
# Database
npx nx database:reset twenty-server # Reset database
npx nx run twenty-server:database:init:prod # Initialize database
npx nx run twenty-server:database:migrate:prod # Run migrations
# Development
npx nx run twenty-server:start # Start the server
npx nx run twenty-server:lint # Run linter (add --fix to auto-fix)
npx nx run twenty-server:typecheck # Type checking
npx nx run twenty-server:test # Run unit tests
npx nx run twenty-server:test:integration:with-db-reset # Run integration tests
# Migrations
npx nx run twenty-server:typeorm migration:generate src/database/typeorm/core/migrations/[name] -d src/database/typeorm/core/core.datasource.ts
# Workspace
npx nx run twenty-server:command workspace:sync-metadata -f # Sync metadata
```
## Usage Guidelines
### For Developers
- Rules are automatically applied based on file context
- Check rule descriptions to understand when they're activated
- Use manual references (`@ruleName`) for additional context
- Keep rules updated as the codebase evolves
### For AI Assistants
- Rules provide consistent guidance across conversations
- Use rule context to maintain coding standards
- Reference specific rules when making recommendations
- Apply rule principles in code suggestions and reviews
## Contributing to Rules
### Adding New Rules
1. Create a new `.mdc` file in this directory
2. Include proper metadata headers with description and globs
3. Write clear, actionable guidelines with examples
4. Test the rule with relevant file patterns
5. Update this README if needed
### Updating Existing Rules
1. Modify the rule content while preserving metadata
2. Test changes with affected file patterns
3. Ensure consistency with other rules
4. Update examples and best practices as needed
## Rule Format Reference
Each rule file uses the MDC format with metadata:
```markdown
---
description: Brief description of the rule's purpose
globs: ["**/*.ts", "**/*.tsx"] # File patterns for auto-attachment
alwaysApply: false # Whether to always include this rule
---
# Rule Title
Rule content in Markdown format...
```
## Migration from Legacy Format
The rules have been migrated from the legacy `.md` format to the modern `.mdc` format, providing:
- Better context awareness through file pattern matching
- Improved organization with metadata headers
- More flexible rule application strategies
- Enhanced integration with Cursor's AI features
For the most up-to-date version of these guidelines, always refer to the files in this directory.
-97
View File
@@ -1,97 +0,0 @@
# Twenty Project Architecture
## Overview
Twenty is an open-source CRM built with modern technologies, using TypeScript for both frontend and backend development. This document outlines the core architectural decisions and structure of the project.
## Monorepo Structure
The project is organized as a monorepo using nx, with the following main packages:
### Main Packages
- `packages/twenty-front`: Main Frontend application
- Technology: React
- Purpose: Provides the main user interface for the CRM
- Key responsibilities: User interactions, state management, data display
- `packages/twenty-server`: Main Backend application
- Technology: NestJS
- Purpose: Handles business logic, data persistence, and API
- Key responsibilities: Data processing, authentication, API endpoints
- `packages/twenty-website`: Marketing Website and Documentation
- Technology: NextJS
- Purpose: Public-facing website and documentation
- Key responsibilities: Marketing content, documentation, SEO
- `packages/twenty-ui`: UI Component Library
- Technology: React
- Purpose: Shared UI components and design system
- Key responsibilities: Reusable components, design consistency
- `packages/twenty-shared`: Shared Utilities
- Purpose: Cross-package shared code between frontend and backend
- Contents: Utils, constants, types, interfaces
## Core Technology Stack
### Package Management
- Package Manager: yarn
- Monorepo Tool: nx
- Benefits: Consistent dependency management, shared configurations
### Database Layer
- Primary Database: PostgreSQL
- Schema Structure:
- Core schema: Main application data
- Metadata schema: Configuration and customization data
- Workspace schemas: One schema per tenant, containing tenant-specific data
- ORM Layer:
- TypeORM: For core and metadata schemas
- Purpose: Type-safe database operations for system data
- Benefits: Strong typing, migration support
- TwentyORM: For workspace schemas
- Purpose: Manages tenant-specific entities and customizations
- Benefits: Dynamic entity management, per-tenant customization
- Example: Entities like CompanyWorkspaceEntity are managed per workspace
### State Management
- Frontend State: Recoil
- Purpose: Global state management
- Use cases: User preferences, UI state, cached data
### Data Layer
- API Technology: GraphQL
- Client: Apollo Client
- Purpose: Data fetching and caching
- Benefits: Type safety, efficient data loading
### Infrastructure
- Cache: Redis
- Purpose: High-performance caching layer
- Use cases: Session data, frequent queries
- Authentication: JWT
- Purpose: Secure user authentication
- Implementation: Token-based auth flow
- Queue System: BullMQ
- Purpose: Background job processing
- Use cases: Emails, exports, imports
- Storage: S3/Local Filesystem
- Purpose: File storage and management
- Flexibility: Configurable for cloud or local storage
### Testing Infrastructure
- Backend Testing:
- Framework: Jest
- API Testing: Supertest
- Coverage: Unit tests, integration tests
- Frontend Testing:
- Framework: Jest
- Component Testing: Storybook
- API Mocking: MSW (Mock Service Worker)
- End-to-End Testing:
- Framework: Playwright
- Coverage: Critical user journeys
+30
View File
@@ -0,0 +1,30 @@
---
description: Twenty CRM architecture overview - monorepo structure, tech stack, and development principles
globs: []
alwaysApply: true
---
# Twenty Architecture
## Tech Stack
- **Frontend**: React 18, TypeScript, Recoil, Styled Components, Vite
- **Backend**: NestJS, TypeORM, PostgreSQL, Redis, GraphQL
- **Monorepo**: Nx workspace with yarn
## Package Structure
```
packages/
├── twenty-front/ # React app
├── twenty-server/ # NestJS API
├── twenty-ui/ # Shared components
├── twenty-shared/ # Common types/utils
└── twenty-emails/ # Email templates
```
## Key Principles
- **Functional components only** (no classes)
- **Named exports only** (no default exports)
- **Types over interfaces** (except for extending third-party)
- **String literals over enums** (except GraphQL)
- **No 'any' type allowed**
- **Event handlers over useEffect** for state updates
+319
View File
@@ -0,0 +1,319 @@
---
description: Process and guidelines for creating release changelogs for Twenty CRM
globs: ["**/releases/*.mdx", "**/releases/**"]
alwaysApply: false
---
# Twenty Release Changelog Process
Complete guide for creating release changelogs, including codebase research, file structure, and content guidelines.
## Prerequisites
Before starting, gather the following information:
### Required Information
**Version Number**: `{VERSION}` (e.g., 1.9.0, 2.0.0, 2.1.0)
**Release Date**: Use today's date in format: YYYY-MM-DD
### Changes/Features to Document
List the features and changes to include in this release:
1. **Feature Name**: ______________________________
- Brief description: ______________________________
- Related area (workflow, UI, backend, etc.): ______________________________
2. **Feature Name**: ______________________________
- Brief description: ______________________________
- Related area: ______________________________
3. **Feature Name**: ______________________________
- Brief description: ______________________________
- Related area: ______________________________
## Codebase Research Guide
If feature descriptions are not provided or need enhancement, research the codebase:
### Where to Look
**For Workflow Features:**
- Frontend: `packages/twenty-front/src/modules/workflow/`
- Backend: `packages/twenty-server/src/modules/workflow/`
- Components: `packages/twenty-front/src/modules/workflow/components/`
**For UI/UX Changes:**
- Components: `packages/twenty-front/src/modules/ui/`
- Layout: `packages/twenty-front/src/modules/layout/`
- Design system: `packages/twenty-ui/src/`
**For Backend/API Features:**
- Server modules: `packages/twenty-server/src/modules/`
- Entities: `packages/twenty-server/src/entities/`
- Services: Look for `*.service.ts` files
**For Database/ORM Changes:**
- Migrations: `packages/twenty-server/src/database/typeorm/`
- Entities: `packages/twenty-server/src/entities/`
### Research Commands
```bash
# Find recent merged PRs (adjust date as needed)
gh pr list --search "merged:>2025-10-01" --limit 50 --state merged
# View recent commits
git log --since="2 weeks ago" --oneline --no-merges
# View commits between releases (replace with actual release tags)
git log v1.7.0..v1.8.0 --oneline
# Search for specific feature keywords in code
grep -r "iterator" packages/twenty-front/src/modules/workflow/
grep -r "bulk select" packages/twenty-front/src/modules/workflow/
# Find recent changes in specific directory
git log --since="2 weeks ago" --oneline -- packages/twenty-front/src/modules/workflow/
```
### Using Codebase Search
Use the AI codebase search to find:
- "How does the workflow iterator node work?"
- "Where is bulk select implemented for workflows?"
- "What changes were made to the search node limit?"
## Step-by-Step Process
### 1. Setup Git Branch
```bash
cd /Users/thomascolasdesfrancs/code/twenty
git checkout main
git pull origin main
git checkout -b {VERSION}
```
Replace `{VERSION}` with the actual version number (e.g., `1.9.0`)
### 2. Create File Structure
**Create changelog file:**
- Path: `packages/twenty-website/src/content/releases/{VERSION}.mdx`
- Example: `packages/twenty-website/src/content/releases/1.9.0.mdx`
**Create image folder:**
- Path: `packages/twenty-website/public/images/releases/{MINOR_VERSION}/`
- Example for version 1.9.0: `packages/twenty-website/public/images/releases/1.9/`
- Example for version 2.0.0: `packages/twenty-website/public/images/releases/2.0/`
```bash
# Create the image folder
mkdir -p packages/twenty-website/public/images/releases/{MINOR_VERSION}
```
### 3. Move Illustration Files
**Source:** `/Users/thomascolasdesfrancs/Downloads/🆕`
**Destination:** `packages/twenty-website/public/images/releases/{MINOR_VERSION}/`
**Naming Convention:** `{VERSION}-descriptive-name.png`
Examples:
- `1.9.0-feature-name.png`
- `1.9.0-another-feature.png`
```bash
# Move and rename files
cp ~/Downloads/🆕/source-file.png packages/twenty-website/public/images/releases/{MINOR_VERSION}/{VERSION}-feature-name.png
```
### 4. Research Features (if needed)
If descriptions are not provided:
1. Use the research commands above to find recent PRs and commits
2. Search the codebase for feature-related code
3. Read PR descriptions for context
4. Check component comments and documentation
### 5. Write Changelog Content
Create the MDX file with this structure:
```markdown
---
release: {VERSION}
Date: {YYYY-MM-DD}
---
# Feature 1 Name
Short description explaining what the feature does and why it's useful. Keep it user-focused and concise (1-2 sentences).
![](/images/releases/{MINOR_VERSION}/{VERSION}-feature-1.png)
# Feature 2 Name
Another short description of the second feature.
![](/images/releases/{MINOR_VERSION}/{VERSION}-feature-2.png)
# Feature 3 Name
Description of the third feature.
![](/images/releases/{MINOR_VERSION}/{VERSION}-feature-3.png)
```
**Style Guidelines:**
- Use H1 (`#`) for feature names
- Keep descriptions to 1-2 sentences
- Focus on user benefits, not technical implementation
- Use active voice
- Start with what the user can now do
**Reference Previous Changelogs:**
- Check `packages/twenty-website/src/content/releases/` for examples
- Recent releases: 1.7.0.mdx, 1.6.0.mdx, 1.5.0.mdx
### 6. Review
Open the changelog file for review:
```bash
# Open in Cursor
cursor packages/twenty-website/src/content/releases/{VERSION}.mdx
# Open image folder to verify illustrations
open packages/twenty-website/public/images/releases/{MINOR_VERSION}
```
Review checklist:
- [ ] Version number is correct in frontmatter
- [ ] Date is today's date
- [ ] All features are documented
- [ ] Image paths are correct
- [ ] Image files exist in the folder
- [ ] Descriptions are clear and user-focused
- [ ] Spelling and grammar are correct
### 7. Present Changelog for User Approval
**IMPORTANT**: Before committing and creating the PR, always show the complete changelog content to the user and wait for explicit approval.
**What to show:**
1. Display the full MDX content of the changelog file
2. Confirm that illustration files were moved to the correct location
3. List the image file names and paths
**What to say:**
```
I've created the changelog for version {VERSION}. Here's the content for your review:
[Show full MDX content]
Images moved to:
- packages/twenty-website/public/images/releases/{MINOR_VERSION}/{VERSION}-feature-1.png
- packages/twenty-website/public/images/releases/{MINOR_VERSION}/{VERSION}-feature-2.png
Please review the content. Once you approve, I'll commit the changes and create the pull request.
```
**Wait for user approval before proceeding to step 8.**
Possible user responses:
- "Looks good" / "Approve" / "Create the PR" → Proceed to step 8
- Requests changes → Make the requested edits, then show content again
- Asks questions → Answer them, then wait for approval
### 8. Commit Changes
```bash
# Check status
git status
# Add files
git add packages/twenty-website/src/content/releases/{VERSION}.mdx
git add packages/twenty-website/public/images/releases/{MINOR_VERSION}/
# Commit
git commit -m "Add {VERSION} release changelog"
# Push branch
git push -u origin {VERSION}
```
### 9. Create Pull Request
```bash
# Create PR using GitHub CLI
gh pr create \
--title "Release {VERSION}" \
--body "## Release {VERSION}
This release includes:
- Feature 1
- Feature 2
- Feature 3
Changelog file: \`packages/twenty-website/src/content/releases/{VERSION}.mdx\`
Release date: {DATE}" \
--base main \
--head {VERSION}
```
Or visit: `https://github.com/twentyhq/twenty/pull/new/{VERSION}`
## File Naming Conventions
### Changelog Files
- **Format**: `{MAJOR}.{MINOR}.{PATCH}.mdx`
- **Convention**: One file per complete version
- **Examples**: `1.6.0.mdx`, `1.7.0.mdx`, `2.0.0.mdx`
- **Location**: `packages/twenty-website/src/content/releases/`
### Image Folders
- **Format**: `{MAJOR}.{MINOR}/`
- **Convention**: One folder per minor version (shared across patches)
- **Examples**: `1.6/`, `1.7/`, `2.0/`
- **Location**: `packages/twenty-website/public/images/releases/`
### Image Files
- **Format**: `{VERSION}-descriptive-name.png`
- **Convention**: Kebab-case descriptive names
- **Examples**:
- `1.8.0-workflow-iterator.png`
- `1.8.0-bulk-select.png`
- `1.9.0-new-feature.png`
## Quick Reference Template
Copy and fill this for each release:
```
VERSION: ___________
DATE: ___________
MINOR_VERSION: ___________
Features to document:
1. ___________________________
2. ___________________________
3. ___________________________
Branch name: {VERSION}
Changelog path: packages/twenty-website/src/content/releases/{VERSION}.mdx
Images path: packages/twenty-website/public/images/releases/{MINOR_VERSION}/
```
## Tips
- **Start early**: Begin documenting features as they're developed
- **User perspective**: Write for users, not developers
- **Be concise**: 1-2 sentences per feature
- **Visual first**: Illustrations should showcase the feature clearly
- **Consistent style**: Match tone and structure of previous changelogs
- **Test links**: Verify all image paths work before committing
- **Research thoroughly**: Use codebase search to understand features deeply
-259
View File
@@ -1,259 +0,0 @@
# Code Style Guidelines
## Core Code Style Principles
Twenty emphasizes clean, readable, and maintainable code. This document outlines our code style conventions and best practices.
## Control Flow
### Early Returns
- Use early returns to reduce nesting
- Handle edge cases first
```typescript
// ✅ Correct
const processUser = (user: User | null) => {
if (!user) return null;
if (!user.isActive) return null;
return {
id: user.id,
name: user.name,
};
};
// ❌ Incorrect
const processUser = (user: User | null) => {
if (user) {
if (user.isActive) {
return {
id: user.id,
name: user.name,
};
}
}
return null;
};
```
### No Nested Ternaries
- Avoid nested ternary operators
- Use if statements or early returns
```typescript
// ✅ Correct
const getUserDisplay = (user: User) => {
if (!user.name) return 'Anonymous';
if (!user.isActive) return 'Inactive User';
return user.name;
};
// ❌ Incorrect
const getUserDisplay = (user: User) =>
user.name
? user.isActive
? user.name
: 'Inactive User'
: 'Anonymous';
```
### No Else-If Chains
- Use switch statements or lookup objects
- Keep conditions flat
```typescript
// ✅ Correct
const getStatusColor = (status: Status): string => {
switch (status) {
case 'success':
return 'green';
case 'warning':
return 'yellow';
case 'error':
return 'red';
default:
return 'gray';
}
};
// Or using a lookup object
const statusColors: Record<Status, string> = {
success: 'green',
warning: 'yellow',
error: 'red',
default: 'gray',
};
// ❌ Incorrect
const getStatusColor = (status: Status): string => {
if (status === 'success') {
return 'green';
} else if (status === 'warning') {
return 'yellow';
} else if (status === 'error') {
return 'red';
} else {
return 'gray';
}
};
```
## Operators and Expressions
### Optional Chaining Over &&
- Use optional chaining for null/undefined checks
- Clearer intent and better type safety
```typescript
// ✅ Correct
const userName = user?.name;
const userAddress = user?.address?.street;
// ❌ Incorrect
const userName = user && user.name;
const userAddress = user && user.address && user.address.street;
```
## Function Design
### Small Focused Functions
- Keep functions small and single-purpose
- Extract complex logic into helper functions
```typescript
// ✅ Correct
const validateUser = (user: User) => {
if (!isValidName(user.name)) return false;
if (!isValidEmail(user.email)) return false;
if (!isValidAge(user.age)) return false;
return true;
};
const isValidName = (name: string) => {
return name.length >= 2 && /^[a-zA-Z\s]*$/.test(name);
};
const isValidEmail = (email: string) => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
};
const isValidAge = (age: number) => {
return age >= 18 && age <= 120;
};
// ❌ Incorrect
const validateUser = (user: User) => {
if (user.name.length < 2 || !/^[a-zA-Z\s]*$/.test(user.name)) return false;
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(user.email)) return false;
if (user.age < 18 || user.age > 120) return false;
return true;
};
```
## Naming and Documentation
### Clear Variable Names
- Use descriptive, intention-revealing names
- Avoid abbreviations unless common
```typescript
// ✅ Correct
const isUserActive = user.status === 'active';
const hasRequiredPermissions = user.permissions.includes('admin');
const userDisplayName = user.name || 'Anonymous';
// ❌ Incorrect
const active = user.status === 'active';
const hasPerm = user.permissions.includes('admin');
const udn = user.name || 'Anonymous';
```
### No Console.logs in Commits
- Remove all console.logs before committing
- Use proper logging/error tracking in production
```typescript
// ❌ Incorrect - Don't commit these
console.log('user:', user);
console.log('debug:', someValue);
// ✅ Correct - Use proper logging
logger.info('User action completed', { userId: user.id });
logger.error('Operation failed', { error });
```
### Minimal Comments
- Write self-documenting code
- Use comments only for complex business logic
```typescript
// ✅ Correct
// Calculate pro-rated amount based on billing cycle
const calculateProRatedAmount = (amount: number, daysLeft: number, totalDays: number) => {
return (amount * daysLeft) / totalDays;
};
// ❌ Incorrect - Unnecessary comments
// Get the user's name
const getUserName = (user: User) => user.name;
// Check if user is active
const isUserActive = (user: User) => user.status === 'active';
```
## Error Handling
### Proper Error Handling
- Use try-catch blocks appropriately
- Provide meaningful error messages
```typescript
// ✅ Correct
const fetchUserData = async (userId: string) => {
try {
const response = await api.get(`/users/${userId}`);
return response.data;
} catch (error) {
logger.error('Failed to fetch user data', {
userId,
error: error instanceof Error ? error.message : 'Unknown error',
});
throw new UserFetchError('Failed to fetch user data');
}
};
// ❌ Incorrect
const fetchUserData = async (userId: string) => {
try {
const response = await api.get(`/users/${userId}`);
return response.data;
} catch (error) {
console.log('error:', error);
throw error;
}
};
```
## Code Organization
### Logical Grouping
- Group related code together
- Maintain consistent organization
```typescript
// ✅ Correct
class UserService {
// Properties
private readonly api: Api;
private readonly logger: Logger;
// Constructor
constructor(api: Api, logger: Logger) {
this.api = api;
this.logger = logger;
}
// Public methods
public async getUser(id: string): Promise<User> {
// Implementation
}
public async updateUser(user: User): Promise<User> {
// Implementation
}
// Private helpers
private validateUser(user: User): boolean {
// Implementation
}
}
```
+172
View File
@@ -0,0 +1,172 @@
---
description: Code style guidelines for Twenty CRM
globs: []
alwaysApply: true
---
# Code Style Guidelines
## Formatting Standards
- **Prettier**: 2-space indentation, single quotes, trailing commas, semicolons
- **Print width**: 80 characters
- **ESLint**: No unused imports, consistent import ordering, prefer const over let
## Naming Conventions
```typescript
// ✅ Variables and functions - camelCase
const userAccountBalance = 1000;
const calculateMonthlyPayment = () => {};
// ✅ Constants - SCREAMING_SNAKE_CASE
const API_ENDPOINTS = {
USERS: '/api/users',
ORDERS: '/api/orders',
} as const;
// ✅ Types and Classes - PascalCase
class UserService {}
type UserAccountData = {};
type ButtonProps = {}; // Component props suffix with 'Props'
// ✅ Files and directories - kebab-case
// user-profile.component.tsx
// user-profile.styles.ts
// ❌ NEVER use abbreviations in variable names
// Bad
const users = data.map((u) => u.name);
const field = items.find((f) => f.id === id);
// Good
const users = data.map((user) => user.name);
const field = items.find((item) => item.id === id);
const fieldMetadata = inlineFields.find(
(fieldMetadataItem) => fieldMetadataItem.name === fieldName,
);
```
## Import Organization
```typescript
// ✅ Correct import order
// 1. External libraries
import React from 'react';
import { useCallback } from 'react';
import styled from 'styled-components';
// 2. Internal modules (absolute paths)
import { Button } from '@/components/ui';
import { UserService } from '@/services';
// 3. Relative imports
import { UserCardProps } from './types';
```
## Function Structure
```typescript
// ✅ Small, focused functions
// ✅ Required parameters first, optional last
const processUserData = (
user: User,
options: ProcessingOptions,
callback?: (result: ProcessedUser) => void
): ProcessedUser => {
const processedUser = transformUserData(user);
applyOptions(processedUser, options);
if (callback) {
callback(processedUser);
}
return processedUser;
};
```
## Comments
```typescript
// ✅ Use short-form comments, NOT JSDoc blocks
// ✅ Explain business logic and non-obvious intentions (WHY, not WHAT)
// Apply 15% discount for premium users with orders > $100
const discount = isPremiumUser && orderTotal > 100 ? 0.15 : 0;
// TODO: Replace with proper authentication service
const isAuthenticated = localStorage.getItem('token') !== null;
// ✅ Multi-line comments use multiple // lines (NOT /** */ blocks)
// Calculates the total price after applying tax and discount
// Returns the final price that should be charged to the customer
const calculateTotalPrice = (basePrice: number): number => {
// Implementation
};
// ❌ AVOID obvious comments that just describe what code does
// Bad: Get all inline fields dynamically
const { inlineFieldMetadataItems } = useFieldListFieldMetadataItems({...});
// Bad: Define standard fields in display order
const standardFieldOrder = ['startsAt', 'endsAt', 'conferenceLink'];
// Bad: Split fields into standard and custom
const standardFields = standardFieldOrder.map(...)
// ✅ GOOD: Only comment if explaining non-obvious business logic
// Calendar events display standard fields first, then custom fields after participants
// to maintain consistency with the legacy UI behavior
const standardFields = standardFieldOrder.map(...)
// ❌ AVOID JSDoc blocks - use short comments instead
/**
* This style is NOT preferred in this codebase
*/
```
**Comment Guidelines:**
- **DO** comment complex business rules or domain-specific logic
- **DO** comment non-obvious algorithmic decisions
- **DO** add TODOs for future improvements
- **DON'T** comment obvious variable declarations or function calls
- **DON'T** comment what is already clear from well-named variables/functions
- **DON'T** add comments that just repeat what the code says
## Utility Helpers
```typescript
// ✅ Use existing utility helpers instead of manual checks
import { isDefined } from 'twenty-shared/utils';
import { isNonEmptyString, isNonEmptyArray } from '@sniptt/guards';
// ❌ Manual type guards
const validItems = items.filter((item): item is Item => item !== undefined);
const hasValue = value !== null && value !== undefined;
// ✅ Use utility helpers
const validItems = items.filter(isDefined);
const hasValue = isDefined(value);
// Other useful helpers:
// - isDefined(value) - checks !== null && !== undefined
// - isNonEmptyString(value) - checks string is defined and not empty
// - isNonEmptyArray(value) - checks array is defined and has items
```
## Security Patterns
```typescript
// ✅ CSV Export: Always apply security first, then formatting
const safeValue = formatValueForCSV(sanitizeValueForCSVExport(userInput));
// ✅ Input validation before processing
const sanitizedInput = validateAndSanitize(userInput);
const result = processData(sanitizedInput);
```
## Error Handling
```typescript
// ✅ Proper error types and meaningful messages
try {
const user = await userService.findById(userId);
if (!user) {
throw new UserNotFoundError(`User with ID ${userId} not found`);
}
return user;
} catch (error) {
logger.error('Failed to fetch user', { userId, error });
throw error;
}
```
+100
View File
@@ -0,0 +1,100 @@
---
description: Guidelines for incorporating user feedback and improving cursor rules
globs: []
alwaysApply: true
---
# Feedback Incorporation Guidelines
## Post-Interaction Reflection
After each coding session or significant interaction, the AI should:
### 1. Reflect on User Feedback
- **Identify patterns** in user corrections or suggestions
- **Note recurring issues** that could be prevented with better rules
- **Recognize gaps** in current cursor rules or guidelines
### 2. Suggest Rule Improvements
When user provides feedback that reveals a pattern or preference:
```typescript
// Example feedback patterns to watch for:
// - "We don't use useEffect, handle state changes in event callbacks"
// - "We don't use JSDoc blocks, prefer // comments"
// - "Always use named exports, never default exports"
// - "We prefer functional components over class components"
// - "Use event handlers over useEffect for state updates"
```
### 3. Proactive Rule Suggestions
At the end of interactions, suggest:
```markdown
## 💡 Suggested Cursor Rule Updates
Based on your feedback today, I recommend adding/updating these rules:
**Code Style Rule Update:**
- Add preference for // comments over JSDoc blocks
- Enforce named exports only (no default exports)
**React Guidelines Update:**
- Document preference for event handlers over useEffect
- Add functional components only rule
Would you like me to help incorporate these into your cursor rules?
```
## Implementation Process
### When to Suggest Updates
- User corrects the same type of mistake multiple times
- User explains a codebase-specific preference
- User points out missing functionality or incomplete implementations
- User provides context about existing patterns not captured in rules
### How to Present Suggestions
1. **Summarize the pattern** observed from feedback
2. **Propose specific rule language** that would prevent the issue
3. **Explain the benefit** of codifying this knowledge
4. **Ask for confirmation** before implementing
### Rule Categories to Consider
- **Code Style**: Formatting, naming, comment styles, export patterns
- **React Patterns**: Hook usage, component structure, state management
- **Architecture**: File organization, import patterns, component composition
- **Testing**: Test structure, naming, coverage expectations
- **Performance**: Optimization patterns, anti-patterns to avoid
## Example Feedback Integration
```markdown
## Today's Learning: React State Management Patterns
**User Feedback Received:**
- "We don't use useEffect, handle state changes in event callbacks"
- "We don't use JSDoc blocks, prefer // comments"
- "Always use named exports, never default exports"
**Proposed Rule Additions:**
```typescript
// ✅ React State Updates - Use event handlers, not useEffect
const handleButtonClick = () => {
setData(newData); // Direct state update in event handler
};
// ❌ Avoid useEffect for state updates
// useEffect(() => { setData(newData); }, [trigger]);
// ✅ Named exports only
export const UserComponent = () => {};
export const useUserData = () => {};
```
**Benefits:**
- Prevents useEffect overuse and related bugs
- Ensures consistent export patterns across codebase
- Documents preferred React patterns for the team
```
This approach helps the AI learn from each interaction and continuously improve the development experience.
-207
View File
@@ -1,207 +0,0 @@
# File Structure Guidelines
## Core File Structure Principles
Twenty follows a modular and organized file structure that promotes maintainability and scalability. This document outlines our file organization conventions and best practices.
## Component Organization
### One Component Per File
- Each component should have its own file
- File name should match component name
```typescript
// ✅ Correct
// UserProfile.tsx
export const UserProfile = () => {
return <div>...</div>;
};
// ❌ Incorrect
// users.tsx
export const UserProfile = () => {
return <div>...</div>;
};
export const UserList = () => {
return <div>...</div>;
};
```
## Directory Structure
### Feature Modules
- Place features in `modules/` directory
- Group related components and logic
```
modules/
├── users/
│ ├── components/
│ │ ├── UserList.tsx
│ │ ├── UserCard.tsx
│ │ └── UserProfile.tsx
│ ├── hooks/
│ │ └── useUser.ts
│ ├── states/
│ │ └── userStates.ts
│ └── types/
│ └── user.ts
├── workspace/
│ ├── components/
│ ├── hooks/
│ └── states/
└── settings/
├── components/
├── hooks/
└── states/
```
### Hooks Organization
- Place hooks in `hooks/` directory
- Group by feature or global usage
```
hooks/
├── useClickOutside.ts
├── useDebounce.ts
└── features/
├── users/
│ ├── useUserActions.ts
│ └── useUserData.ts
└── workspace/
└── useWorkspaceSettings.ts
```
### State Management
- Place state definitions in `states/` directory
- Organize by feature
```
states/
├── global/
│ ├── theme.ts
│ └── navigation.ts
├── users/
│ ├── atoms.ts
│ └── selectors.ts
└── workspace/
├── atoms.ts
└── selectors.ts
```
### Types Organization
- Place types in `types/` directory
- Group by domain or feature
```
types/
├── common.ts
├── api.ts
└── features/
├── user.ts
├── workspace.ts
└── settings.ts
```
## Naming Conventions
### Component Files
- Use PascalCase for component files
- Use descriptive, feature-specific names
```
components/
├── UserProfile.tsx
├── UserProfileHeader.tsx
└── UserProfileContent.tsx
```
### Non-Component Files
- Use camelCase for non-component files
- Use clear, descriptive names
```
hooks/
├── useClickOutside.ts
└── useDebounce.ts
utils/
├── dateFormatter.ts
└── stringUtils.ts
```
## Module Structure
### Feature Module Organization
- Consistent structure across features
- Clear separation of concerns
```
modules/users/
├── components/
│ ├── UserList/
│ │ ├── UserList.tsx
│ │ ├── UserListItem.tsx
│ │ └── UserListHeader.tsx
│ └── UserProfile/
│ ├── UserProfile.tsx
│ └── UserProfileHeader.tsx
├── hooks/
│ ├── useUserList.ts
│ └── useUserProfile.ts
├── states/
│ ├── atoms.ts
│ └── selectors.ts
├── types/
│ └── user.ts
└── utils/
└── userFormatter.ts
```
## Best Practices
### Import Organization
- Group imports by type
- Maintain consistent order
```typescript
// External dependencies
import { useState } from 'react';
import { styled } from '@emotion/styled';
// Internal modules
import { useUser } from '~/modules/users/hooks';
import { userState } from '~/modules/users/states';
// Local imports
import { UserAvatar } from './UserAvatar';
import { type UserProfileProps } from './types';
```
### Path Aliases
- Use path aliases for better imports
- Avoid deep relative paths
```typescript
// ✅ Correct
import { Button } from '~/components/Button';
import { useUser } from '~/modules/users/hooks';
// ❌ Incorrect
import { Button } from '../../../components/Button';
import { useUser } from '../../../modules/users/hooks';
```
### Component Co-location
- Keep related files close together
- Use index files for public APIs
```
components/UserProfile/
├── UserProfile.tsx
├── UserProfileHeader.tsx
├── UserProfileContent.tsx
├── styles.ts
├── types.ts
└── index.ts
```
### Test File Location
- Place test files next to implementation
- Use `.test.ts` or `.spec.ts` extension
```
components/
├── UserProfile.tsx
├── UserProfile.test.tsx
├── UserProfile.stories.tsx
└── types.ts
```
+107
View File
@@ -0,0 +1,107 @@
---
description: File structure guidelines for Twenty CRM
globs: []
alwaysApply: true
---
# File Structure Guidelines
## Directory Organization
```
packages/twenty-front/src/
├── components/ # Reusable UI components
├── pages/ # Route components
├── modules/ # Feature modules
├── hooks/ # Custom hooks
├── services/ # API services
└── types/ # Type definitions
packages/twenty-server/src/
├── modules/ # Feature modules
├── entities/ # Database entities
├── dto/ # Data transfer objects
└── utils/ # Helper functions
```
## File Naming
- **kebab-case** for all files and directories
- **Descriptive suffixes** for clarity
```
// ✅ Correct naming
user-profile.component.tsx
user-profile.styles.ts
user-profile.test.tsx
user.service.ts
user.entity.ts
create-user.dto.ts
```
## Index Files & Barrel Exports
```typescript
// ✅ Clean barrel exports in index.ts
export { UserCard } from './user-card.component';
export { UserList } from './user-list.component';
export type { UserCardProps, UserListProps } from './types';
// ✅ Usage - clean imports
import { UserCard, UserList } from '@/components/user';
```
## Module Structure
```
src/modules/user/
├── components/ # Module-specific components
├── hooks/ # Module hooks
├── services/ # API services
├── types/ # Type definitions
└── index.ts # Module exports
```
## Import/Export Patterns
```typescript
// ✅ Import organization
// 1. External libraries
import React from 'react';
import styled from 'styled-components';
// 2. Internal modules (absolute paths)
import { Button } from '@/components/ui';
import { UserService } from '@/services';
// 3. Relative imports
import { UserCardProps } from './types';
// ✅ Named exports only (no default exports)
export const UserComponent = ({ user }: UserProps) => {
// Component implementation
};
```
## File Size Guidelines
- **Components**: Under 300 lines
- **Services**: Under 500 lines
- **Extract logic** into hooks/utilities when files grow large
- **Use composition** over large monolithic components
## Configuration Files
### Project Configuration
```
.vscode/ # VSCode settings
├── settings.json
├── extensions.json
└── launch.json
.github/ # GitHub workflows
├── workflows/
└── templates/
.cursor/ # Cursor rules
├── rules/
└── environment.json
```
### Build Configuration
- Keep build configs in root or package directories
- Use consistent naming for config files
- Comment complex configurations
- Version control all configuration files
+78
View File
@@ -0,0 +1,78 @@
---
description: Guidelines and best practices for working with Nx in the Twenty workspace, including workspace architecture understanding, configuration management, and generator usage.
globs: ["**/nx.json", "**/project.json", "**/workspace.json"]
alwaysApply: true
---
# Nx Guidelines
## Core Commands
```bash
# Run target for specific project
npx nx run twenty-front:build
npx nx run twenty-server:test
# Run target for all projects
npx nx run-many --target=build --all
npx nx run-many --target=test --projects=twenty-front,twenty-server
# Generate/modify projects
npx nx g @nx/react:app my-app
npx nx g @nx/react:component my-component
```
## Project Structure
- Each package has a `project.json` with targets
- Dependencies managed through `tsconfig.json` path mappings
- Shared libraries in `packages/` directory
## Build Targets
```json
// project.json
{
"targets": {
"build": {
"executor": "@nx/vite:build",
"options": { "outputPath": "dist/packages/twenty-front" }
},
"test": {
"executor": "@nx/jest:jest",
"options": { "jestConfig": "packages/twenty-front/jest.config.mjs" }
}
}
}
```
## Dependency Graph
```bash
# View project dependencies
npx nx graph
# Check what's affected by changes
npx nx affected --target=test
npx nx affected --target=build --base=main
```
## Library Management
- Use `npx nx g @nx/workspace:library` generator for shared libs
- Internal imports use `@/` path mapping
- Libraries must export through index.ts barrel files
## Cache Configuration
- Nx caches build outputs and test results
- Configure `outputs` in project.json targets
- Use `inputs` to define what invalidates cache
```json
{
"build": {
"outputs": ["dist/packages/my-app"],
"inputs": ["source", "^source"],
"cache": true
}
}
```
-220
View File
@@ -1,220 +0,0 @@
# React Guidelines
## Core React Principles
Twenty follows modern React best practices with a focus on functional components and clean, maintainable code. This document outlines our React conventions and best practices.
## Component Structure
### Functional Components Only
- Use functional components exclusively
- No class components allowed
```typescript
// ✅ Correct
export const UserProfile = ({ user }: UserProfileProps) => {
return (
<StyledContainer>
<h1>{user.name}</h1>
</StyledContainer>
);
};
// ❌ Incorrect
export class UserProfile extends React.Component<UserProfileProps> {
render() {
return (
<StyledContainer>
<h1>{this.props.user.name}</h1>
</StyledContainer>
);
}
}
```
### Named Exports
- Use named exports exclusively
- No default exports
```typescript
// ✅ Correct
export const Button = ({ label }: ButtonProps) => {
return <button>{label}</button>;
};
// ❌ Incorrect
export default function Button({ label }: ButtonProps) {
return <button>{label}</button>;
}
```
## State and Effects
### Event Handlers Over useEffect
- Prefer event handlers for state updates
- Avoid useEffect for state synchronization
```typescript
// ✅ Correct
const UserForm = () => {
const handleSubmit = async (data: FormData) => {
await updateUser(data);
refreshUserList();
};
return <Form onSubmit={handleSubmit} />;
};
// ❌ Incorrect
const UserForm = () => {
useEffect(() => {
if (formData) {
updateUser(formData);
}
}, [formData]);
return <Form />;
};
```
## Component Design
### Small, Focused Components
- Keep components small and single-purpose
- Extract reusable logic into custom hooks
```typescript
// ✅ Correct
const UserCard = ({ user }: UserCardProps) => {
return (
<StyledCard>
<UserAvatar user={user} />
<UserInfo user={user} />
<UserActions user={user} />
</StyledCard>
);
};
// ❌ Incorrect
const UserCard = ({ user }: UserCardProps) => {
return (
<StyledCard>
{/* Too much logic in one component */}
<img src={user.avatar} />
<div>{user.name}</div>
<div>{user.email}</div>
<button onClick={() => handleEdit(user)}>Edit</button>
<button onClick={() => handleDelete(user)}>Delete</button>
{/* More complex logic... */}
</StyledCard>
);
};
```
## Props
### Prop Naming
- Use clear, descriptive prop names
- Follow React conventions (onClick, isActive, etc.)
```typescript
// ✅ Correct
type ButtonProps = {
onClick: () => void;
isDisabled?: boolean;
isLoading?: boolean;
};
// ❌ Incorrect
type ButtonProps = {
clickHandler: () => void;
disabled?: boolean;
loading?: boolean;
};
```
### Prop Destructuring
- Destructure props with proper typing
- Use TypeScript for prop types
```typescript
// ✅ Correct
const Button = ({ onClick, isDisabled, children }: ButtonProps) => {
return (
<button onClick={onClick} disabled={isDisabled}>
{children}
</button>
);
};
// ❌ Incorrect
const Button = (props: ButtonProps) => {
return (
<button onClick={props.onClick} disabled={props.isDisabled}>
{props.children}
</button>
);
};
```
## Performance Optimization
### Memoization
- Use memo for expensive computations
- Avoid premature optimization
```typescript
// ✅ Correct - Complex computation
const MemoizedChart = memo(({ data }: ChartProps) => {
// Complex rendering logic
return <ComplexChart data={data} />;
});
// ❌ Incorrect - Unnecessary memoization
const MemoizedText = memo(({ text }: { text: string }) => {
return <span>{text}</span>;
});
```
### Event Handlers
- Use callback refs for DOM manipulation
- Memoize callbacks when needed
```typescript
// ✅ Correct
const UserList = () => {
const handleScroll = useCallback((event: UIEvent) => {
// Complex scroll handling
}, []);
return <div onScroll={handleScroll}>{/* content */}</div>;
};
```
## Error Handling
### Error Boundaries
- Use error boundaries for component error handling
- Provide meaningful fallback UIs
```typescript
// ✅ Correct
const ErrorFallback = ({ error }: { error: Error }) => (
<StyledError>
<h2>Something went wrong</h2>
<pre>{error.message}</pre>
</StyledError>
);
const SafeComponent = () => (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<ComponentThatMightError />
</ErrorBoundary>
);
```
### Loading States
- Handle loading states gracefully
- Provide meaningful loading indicators
```typescript
// ✅ Correct
const UserProfile = () => {
const { data: user, isLoading, error } = useUser();
if (isLoading) return <LoadingSpinner />;
if (error) return <ErrorMessage error={error} />;
if (!user) return <NotFound />;
return <UserProfileContent user={user} />;
};
```
@@ -0,0 +1,85 @@
---
description: React general guidelines for Twenty CRM
alwaysApply: false
---
# React Guidelines
## Core Rules
- **Functional components only** (no classes)
- **Named exports only** (no default exports)
- **Event handlers over useEffect** for state updates
## Component Structure
```typescript
// ✅ Correct
export const UserProfile = ({ user, onEdit }: UserProfileProps) => {
const handleEdit = () => onEdit(user.id);
return (
<StyledContainer>
<h1>{user.name}</h1>
<Button onClick={handleEdit}>Edit</Button>
</StyledContainer>
);
};
```
## Props & Event Handlers
```typescript
// ✅ Correct - Destructure props
const Button = ({ onClick, isDisabled, children }: ButtonProps) => (
<button onClick={onClick} disabled={isDisabled}>
{children}
</button>
);
// ✅ Correct - Event handlers over useEffect
const UserForm = ({ onSubmit }: UserFormProps) => {
const handleSubmit = async (data: FormData) => {
await onSubmit(data);
// Direct event handling, not useEffect
};
return <Form onSubmit={handleSubmit} />;
};
```
## Component Design
- **Small, focused components** - Single responsibility
- **Composition over inheritance** - Combine simple components
- **Extract complex logic** into custom hooks
```typescript
// ✅ Good - Composed from smaller components
const UserCard = ({ user }: UserCardProps) => (
<StyledCard>
<UserAvatar user={user} />
<UserInfo user={user} />
<UserActions user={user} />
</StyledCard>
);
```
## Performance
```typescript
// ✅ Use memo for expensive components only
const ExpensiveChart = memo(({ data }: ChartProps) => {
// Complex rendering logic
return <ComplexChart data={data} />;
});
// ✅ Memoize callbacks when needed
const UserList = ({ users, onUserSelect }: UserListProps) => {
const handleUserSelect = useCallback((user: User) => {
onUserSelect(user);
}, [onUserSelect]);
return (
<div>
{users.map(user => (
<UserItem key={user.id} user={user} onSelect={handleUserSelect} />
))}
</div>
);
};
```
@@ -1,219 +0,0 @@
# State Management Guidelines
## Core State Management Principles
Twenty uses a combination of Recoil for global state and Apollo Client for server state management. This document outlines our state management conventions and best practices.
## Global State Management
### Recoil Usage
- Use Recoil for global application state
- Keep atoms small and focused
```typescript
// ✅ Correct
// states/theme.ts
export const themeState = atom<'light' | 'dark'>({
key: 'themeState',
default: 'light',
});
// states/user.ts
export const userState = atom<User | null>({
key: 'userState',
default: null,
});
// ❌ Incorrect
// states/globalState.ts
export const globalState = atom({
key: 'globalState',
default: {
theme: 'light',
user: null,
settings: {},
// ... many other unrelated pieces of state
},
});
```
### Atom Organization
- Place atoms in the `states/` directory
- Group related atoms in feature-specific files
```typescript
// states/workspace/atoms.ts
export const workspaceIdState = atom<string>({
key: 'workspaceIdState',
default: '',
});
export const workspaceSettingsState = atom<WorkspaceSettings>({
key: 'workspaceSettingsState',
default: defaultSettings,
});
```
## Server State Management
### Apollo Client Usage
- Use Apollo Client for all GraphQL operations
- Leverage Apollo's caching capabilities
```typescript
// ✅ Correct
const { data, loading } = useQuery(GET_USER_QUERY, {
variables: { id },
fetchPolicy: 'cache-first',
});
// ❌ Incorrect
const [user, setUser] = useState(null);
useEffect(() => {
fetch('/api/user/' + id).then(setUser);
}, [id]);
```
### Query Organization
- Separate operation files
- Use fragments for shared fields
```typescript
// queries/user.ts
export const UserFragment = gql`
fragment UserFields on User {
id
name
email
}
`;
export const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
...UserFields
}
}
${UserFragment}
`;
```
## State Management Best Practices
### Multiple Small Atoms
- Prefer multiple small atoms over prop drilling
- Keep atoms focused on specific features
```typescript
// ✅ Correct
export const selectedViewState = atom<string>({
key: 'selectedViewState',
default: '',
});
export const viewFiltersState = atom<ViewFilters>({
key: 'viewFiltersState',
default: {},
});
// ❌ Incorrect - Prop drilling
const ViewContainer = ({ selectedView, filters, onViewChange }) => {
return (
<ViewHeader view={selectedView} onViewChange={onViewChange}>
<ViewContent>
<ViewFilters filters={filters} />
</ViewContent>
</ViewHeader>
);
};
```
### No useRef for State
- Never use useRef for state management
- Use proper state management tools
```typescript
// ✅ Correct
const [count, setCount] = useState(0);
// or
const [count, setCount] = useRecoilState(countState);
// ❌ Incorrect
const countRef = useRef(0);
```
### Data Fetching
- Extract data fetching to sibling components
- Keep components focused on presentation
```typescript
// ✅ Correct
const UserProfileContainer = () => {
const { data, loading } = useQuery(GET_USER);
if (loading) return <LoadingSpinner />;
return <UserProfile user={data.user} />;
};
const UserProfile = ({ user }: UserProfileProps) => {
return <div>{user.name}</div>;
};
// ❌ Incorrect
const UserProfile = () => {
const { data, loading } = useQuery(GET_USER);
if (loading) return <LoadingSpinner />;
return <div>{data.user.name}</div>;
};
```
### Hook Usage
- Use appropriate hooks for state access
- Choose between useRecoilValue and useRecoilState based on needs
```typescript
// ✅ Correct - Read-only access
const theme = useRecoilValue(themeState);
// ✅ Correct - Read-write access
const [theme, setTheme] = useRecoilState(themeState);
// ❌ Incorrect - Using state setter when only reading
const [theme, _] = useRecoilState(themeState);
```
## Performance Considerations
### Selector Usage
- Use selectors for derived state
- Memoize complex calculations
```typescript
// ✅ Correct
const filteredUsersState = selector({
key: 'filteredUsersState',
get: ({ get }) => {
const users = get(usersState);
const filter = get(userFilterState);
return users.filter(user =>
user.name.toLowerCase().includes(filter.toLowerCase())
);
},
});
// ❌ Incorrect - Calculating in component
const UserList = () => {
const users = useRecoilValue(usersState);
const filter = useRecoilValue(userFilterState);
const filteredUsers = users.filter(user =>
user.name.toLowerCase().includes(filter.toLowerCase())
);
return <List users={filteredUsers} />;
};
```
### Cache Management
- Configure appropriate cache policies
- Handle cache invalidation properly
```typescript
// ✅ Correct
const [updateUser] = useMutation(UPDATE_USER, {
update: (cache, { data }) => {
cache.modify({
id: cache.identify(data.updateUser),
fields: {
name: () => data.updateUser.name,
},
});
},
});
```
+80
View File
@@ -0,0 +1,80 @@
---
description: React state management guidelines for Twenty CRM
alwaysApply: false
---
# React State Management
## Recoil Patterns
```typescript
// ✅ Atoms for primitive state
export const currentUserState = atom<User | null>({
key: 'currentUserState',
default: null,
});
// ✅ Selectors for derived state
export const userDisplayNameSelector = selector({
key: 'userDisplayNameSelector',
get: ({ get }) => {
const user = get(currentUserState);
return user ? `${user.firstName} ${user.lastName}` : 'Guest';
},
});
// ✅ Atom families for dynamic atoms
export const userByIdState = atomFamily<User | null, string>({
key: 'userByIdState',
default: null,
});
```
## Local State Guidelines
```typescript
// ✅ Multiple useState for unrelated state
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [data, setData] = useState<User[]>([]);
// ✅ useReducer for complex state logic
type FormAction =
| { type: 'SET_FIELD'; field: string; value: string }
| { type: 'SET_ERRORS'; errors: Record<string, string> }
| { type: 'RESET' };
const formReducer = (state: FormState, action: FormAction): FormState => {
switch (action.type) {
case 'SET_FIELD':
return { ...state, [action.field]: action.value };
case 'SET_ERRORS':
return { ...state, errors: action.errors };
case 'RESET':
return initialFormState;
default:
return state;
}
};
```
## Data Flow Rules
- **Props down, events up** - Unidirectional data flow
- **Avoid bidirectional binding** - Use callback functions
- **Normalize complex data** - Use lookup tables over nested objects
```typescript
// ✅ Normalized state structure
type UsersState = {
byId: Record<string, User>;
allIds: string[];
};
// ✅ Functional state updates
const increment = useCallback(() => {
setCount(prev => prev + 1);
}, []);
```
## Performance Tips
- Use atom families for dynamic data collections
- Implement proper selector caching
- Avoid heavy computations in selectors
- Batch state updates when possible
-253
View File
@@ -1,253 +0,0 @@
# Testing Guidelines
## Core Testing Principles
Twenty follows a comprehensive testing strategy across all packages, ensuring high-quality, maintainable code. This document outlines our testing conventions and best practices.
## Testing Stack
### Backend Testing
- Primary Framework: Jest
- API Testing: Supertest
- Coverage Requirements: 80% minimum
### Frontend Testing
- Component Testing: Jest + React Testing Library
- Visual Testing: Storybook
- API Mocking: MSW (Mock Service Worker)
### End-to-End Testing
- Framework: Playwright
- Coverage: Critical user journeys
- Cross-browser testing
## Test Organization
### Test File Location
- Co-locate tests with implementation files
- Use consistent naming patterns
```
src/
├── components/
│ ├── UserProfile.tsx
│ ├── UserProfile.test.tsx
│ └── UserProfile.stories.tsx
```
### Test File Naming
- Use `.test.ts(x)` for unit/integration tests
- Use `.spec.ts(x)` for E2E tests
- Use `.stories.tsx` for Storybook stories
## Unit Testing
### Component Testing
- Test behavior, not implementation
- Use React Testing Library best practices
```typescript
// ✅ Correct
test('displays user name when provided', () => {
render(<UserProfile user={{ name: 'John Doe' }} />);
expect(screen.getByText('John Doe')).toBeInTheDocument();
});
// ❌ Incorrect - Testing implementation details
test('sets the text content', () => {
const { container } = render(<UserProfile user={{ name: 'John Doe' }} />);
expect(container.querySelector('h1').textContent).toBe('John Doe');
});
```
### Hook Testing
- Use `renderHook` from @testing-library/react-hooks
- Test all possible states
```typescript
// ✅ Correct
test('useUser hook manages user state', () => {
const { result } = renderHook(() => useUser());
act(() => {
result.current.setUser({ id: '1', name: 'John' });
});
expect(result.current.user).toEqual({ id: '1', name: 'John' });
});
```
### Mocking
- Mock external dependencies
- Use jest.mock for module mocking
```typescript
// ✅ Correct
jest.mock('~/services/api', () => ({
fetchUser: jest.fn().mockResolvedValue({ id: '1', name: 'John' }),
}));
test('fetches and displays user', async () => {
render(<UserProfile userId="1" />);
expect(await screen.findByText('John')).toBeInTheDocument();
});
```
## Integration Testing
### API Testing
- Test complete request/response cycles
- Use Supertest for backend API testing
```typescript
// ✅ Correct
describe('GET /api/users/:id', () => {
it('returns user when found', async () => {
const response = await request(app)
.get('/api/users/1')
.expect(200);
expect(response.body).toEqual({
id: '1',
name: 'John Doe',
});
});
it('returns 404 when user not found', async () => {
await request(app)
.get('/api/users/999')
.expect(404);
});
});
```
## E2E Testing
### Test Structure
- Organize by user journey
- Use page objects for reusability
```typescript
// pages/login.ts
export class LoginPage {
async login(email: string, password: string) {
await this.page.fill('[data-testid="email-input"]', email);
await this.page.fill('[data-testid="password-input"]', password);
await this.page.click('[data-testid="login-button"]');
}
}
// tests/auth.spec.ts
test('user can login successfully', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.login('user@example.com', 'password');
await expect(page).toHaveURL('/dashboard');
});
```
### Test Data
- Use dedicated test environments
- Reset state between tests
```typescript
// ✅ Correct
beforeEach(async () => {
await resetDatabase();
await seedTestData();
});
test('user workflow', async ({ page }) => {
// Test with clean, predictable state
});
```
## Visual Testing
### Storybook Guidelines
- Create stories for all components
- Document component variants
```typescript
// Button.stories.tsx
export default {
title: 'Components/Button',
component: Button,
} as Meta;
export const Primary = {
args: {
variant: 'primary',
label: 'Primary Button',
},
};
export const Secondary = {
args: {
variant: 'secondary',
label: 'Secondary Button',
},
};
```
### Visual Regression
- Use Storybook's visual regression testing
- Review changes carefully
```typescript
// jest.config.js
module.exports = {
preset: 'jest-image-snapshot',
setupFilesAfterEnv: ['<rootDir>/setup-tests.ts'],
};
// Button.visual.test.tsx
describe('Button', () => {
it('matches visual snapshot', async () => {
const image = await page.screenshot();
expect(image).toMatchImageSnapshot();
});
});
```
## Test Quality
### Test Data Attributes
- Use data-testid for test selectors
- Avoid selecting by CSS classes
```typescript
// ✅ Correct
<button data-testid="submit-button">Submit</button>
// In tests
const button = screen.getByTestId('submit-button');
// ❌ Incorrect
const button = container.querySelector('.submit-btn');
```
### Assertion Best Practices
- Use explicit assertions
- Test both positive and negative cases
```typescript
// ✅ Correct
test('form validation', async () => {
render(<UserForm />);
// Negative case
await userEvent.click(screen.getByText('Submit'));
expect(screen.getByText('Name is required')).toBeInTheDocument();
// Positive case
await userEvent.type(screen.getByLabelText('Name'), 'John Doe');
await userEvent.click(screen.getByText('Submit'));
expect(screen.queryByText('Name is required')).not.toBeInTheDocument();
});
```
### Coverage Requirements
- A new feature should have at least 80% coverage
- Focus on critical paths
- Run coverage reports in CI
```typescript
// jest.config.js
module.exports = {
coverageThreshold: {
global: {
statements: 80,
branches: 80,
functions: 80,
lines: 80,
},
},
};
```
+127
View File
@@ -0,0 +1,127 @@
---
description: Testing guidelines for Twenty CRM
alwaysApply: false
---
# Testing Guidelines
## Test Structure (AAA Pattern)
```typescript
describe('UserService', () => {
describe('when getting user by ID', () => {
it('should return user data for valid ID', async () => {
// Arrange
const userId = '123';
const expectedUser = { id: '123', name: 'John' };
mockUserRepository.findById.mockResolvedValue(expectedUser);
// Act
const result = await userService.getUserById(userId);
// Assert
expect(result).toEqual(expectedUser);
});
});
});
```
## React Component Testing
```typescript
// ✅ Test user behavior, not implementation
describe('LoginForm', () => {
it('should display error message for invalid credentials', async () => {
const mockOnSubmit = jest.fn().mockRejectedValue(new Error('Invalid credentials'));
render(<LoginForm onSubmit={mockOnSubmit} />);
await user.type(screen.getByLabelText(/email/i), 'invalid@example.com');
await user.type(screen.getByLabelText(/password/i), 'wrongpassword');
await user.click(screen.getByRole('button', { name: /sign in/i }));
expect(await screen.findByText(/invalid credentials/i)).toBeInTheDocument();
});
});
```
## Mocking Patterns
```typescript
// ✅ Service mocking
const mockEmailService = {
sendEmail: jest.fn().mockResolvedValue({ success: true }),
validateEmail: jest.fn().mockReturnValue(true),
};
// ✅ Test data factories
const createTestUser = (overrides = {}) => ({
id: uuid(),
email: 'test@example.com',
name: 'Test User',
...overrides,
});
beforeEach(() => {
jest.clearAllMocks();
});
```
## Testing Principles
- **Test behavior, not implementation** - Focus on what users see/do
- **Use descriptive test names** - "should [behavior] when [condition]"
- **Query by user-visible elements** - text, roles, labels over test IDs
- **Keep tests isolated** - Independent and repeatable
- **70% unit, 20% integration, 10% E2E** - Test pyramid
## Running Tests
### Single Test File Execution
```bash
# ✅ Run a specific test file (PREFERRED - Fast & Efficient)
npx jest path/to/test.test.ts --config=packages/PROJECT/jest.config.mjs
# Key Benefits:
# - Only runs the specific test file (fast)
# - No dependency resolution overhead
# - Immediate feedback for test development
# ✅ Examples:
# Frontend tests (use .test.ts extension)
npx jest packages/twenty-front/src/modules/localization/utils/detection/detectNumberFormat.test.ts --config=packages/twenty-front/jest.config.mjs
# Server tests (use .spec.ts extension)
npx jest packages/twenty-server/src/utils/__test__/is-work-email.spec.ts --config=packages/twenty-server/jest.config.mjs
# ❌ AVOID - This runs ALL tests (slow):
npx nx test twenty-front --testPathPattern=detectNumberFormat.test.ts
# ✅ Run tests in watch mode for development:
npx jest path/to/test.test.ts --config=packages/twenty-front/jest.config.mjs --watch
# ✅ Run with coverage for single file:
npx jest path/to/test.test.ts --config=packages/twenty-front/jest.config.mjs --coverage
```
### Test Suite Execution
```bash
# Run all tests for a project (use sparingly)
npx nx test twenty-front
npx nx test twenty-server
# Run tests matching a pattern
npx jest --testNamePattern="UserService" --config=packages/twenty-front/jest.config.mjs
```
## Common Patterns
```typescript
// Async testing
await waitFor(() => {
expect(screen.getByText('Loading...')).not.toBeInTheDocument();
});
// User interactions
await user.click(screen.getByRole('button'));
await user.type(screen.getByLabelText(/search/i), 'query');
// API integration tests
const response = await request(app)
.post('/api/users')
.send(userData)
.expect(201);
```
-162
View File
@@ -1,162 +0,0 @@
# Translation Guidelines
## Core Translation Principles
Twenty uses Lingui for internationalization (i18n) and Crowdin for translation management. This document outlines our translation workflow and best practices.
## Technology Stack
### Translation Tools
- **Framework**: @lingui/react
- **Translation Management**: Crowdin
- **Workflow**: GitHub Actions for automation
### Package Structure
Translation files are managed in multiple packages:
- `twenty-front`: Frontend translations
- `twenty-server`: Backend translations
- `twenty-emails`: Email template translations
## Translation Process
### Adding New Strings
#### Using Lingui Macros
- Use `<Trans>` for components
- Use `t` macro for strings outside JSX
```typescript
// ✅ Correct - In JSX
import { Trans } from '@lingui/react/macro';
const WelcomeMessage = () => (
<h1>
<Trans>Welcome to Twenty</Trans>
</h1>
);
// ✅ Correct - Outside JSX
import { t } from '@lingui/react/macro';
const getMessage = () => {
return t`Welcome to Twenty`;
};
// ❌ Incorrect - Don't use raw strings
const WelcomeMessage = () => (
<h1>Welcome to Twenty</h1>
);
```
### String Guidelines
#### What to Translate
- User interface text
- Error messages
- Notifications
- Email content
#### What Not to Translate
- Variables
- Test data/mocks
### Translation Workflow
#### 1. Extracting Translations
- Automatically triggered on main branch changes
- Can be manually triggered in GitHub Actions
- Process:
```bash
# Extract new strings
nx run twenty-front:lingui:extract
nx run twenty-server:lingui:extract
nx run twenty-emails:lingui:extract
```
#### 2. Translation Management
- Translations are managed in Crowdin
- Changes are synced every 2 hours
- Process:
1. New strings are uploaded to Crowdin
2. Translators work on translations
3. Translations are pulled back to the repository
#### 3. Compiling Translations
- Happens automatically in CI/CD
- Required before running the application
```bash
# Compile translations
nx run twenty-front:lingui:compile
nx run twenty-server:lingui:compile
nx run twenty-emails:lingui:compile
```
## Best Practices
### String Management
#### Use Placeholders
- Use placeholders for dynamic content
```typescript
// ✅ Correct
<Trans>Hello {userName},</Trans>
// ❌ Incorrect - String concatenation
<Trans>Hello </Trans>{userName},
```
#### Provide Context
- Lingui provides powerfulway to add context for translators but we don't use them as of today.
### Code Organization
#### Translation Files
- Keep translation files organized by feature
- Use consistent naming patterns
```
src/
├── locales/
│ ├── en/
│ │ ├── messages.po
│ │ └── messages.js
│ └── fr/
│ ├── messages.po
│ └── messages.js
```
### Quality Assurance
#### Strict Mode
- Use --strict mode when compiling to identify missing translations
#### Testing Translations
- Test with different locales
- Verify string interpolation
- Check layout with different language lengths
## Automation
### GitHub Actions
#### Pull Workflow
- Runs every 2 hours
- Downloads new translations from Crowdin
- Creates PR if changes detected
- Can be manually triggered with force pull option
#### Push Workflow
- Runs on main branch changes
- Extracts and uploads new strings
- Compiles translations
- Creates PR with changes
### Error Handling
#### Missing Translations
- Development: Shown in original language
- Production: Falls back to default language
- Strict mode in CI catches missing translations
#### Compilation Errors
- Addressed before merging
- PR created for fixing missing translations
- Automated testing in CI pipeline
+290
View File
@@ -0,0 +1,290 @@
---
description: Translation guidelines for Twenty CRM
alwaysApply: false
---
# Translation Guidelines
## Internationalization (i18n) Overview
### Supported Languages
- English (en) - Primary language
- French (fr) - Secondary language
- German (de) - Planned
- Spanish (es) - Planned
- Additional languages based on community contributions
### i18n Architecture
- Use react-i18next for React components
- Store translations in JSON files
- Implement namespace-based organization
- Support for interpolation and pluralization
## File Structure
### Translation Files
```
src/locales/
├── en/ # English translations
│ ├── common.json # Common UI strings
│ ├── auth.json # Authentication strings
│ ├── dashboard.json # Dashboard specific
│ ├── forms.json # Form labels and validation
│ └── errors.json # Error messages
├── fr/ # French translations
│ ├── common.json
│ ├── auth.json
│ └── ...
└── index.ts # i18n configuration
```
### Translation Keys
- Use nested objects for organization
- Follow consistent naming patterns
- Include context in key names
```json
{
"auth": {
"login": {
"title": "Sign In",
"email": "Email Address",
"password": "Password",
"submit": "Sign In",
"forgotPassword": "Forgot Password?"
},
"register": {
"title": "Create Account",
"confirmPassword": "Confirm Password"
}
}
}
```
## Translation Implementation
### React Components
- Use useTranslation hook
- Specify namespaces for better organization
- Handle loading states properly
```typescript
// ✅ Correct
import { useTranslation } from 'react-i18next';
const LoginForm = () => {
const { t } = useTranslation('auth');
return (
<form>
<h1>{t('login.title')}</h1>
<input
placeholder={t('login.email')}
type="email"
/>
<input
placeholder={t('login.password')}
type="password"
/>
<button type="submit">
{t('login.submit')}
</button>
</form>
);
};
```
### Interpolation
- Use interpolation for dynamic content
- Pass variables through t() function
- Keep interpolation simple and readable
```typescript
// ✅ Correct
const WelcomeMessage = ({ userName }: { userName: string }) => {
const { t } = useTranslation('common');
return (
<h1>{t('welcome.message', { name: userName })}</h1>
);
};
// Translation file
{
"welcome": {
"message": "Welcome back, {{name}}!"
}
}
```
### Pluralization
- Handle singular/plural forms correctly
- Use count-based pluralization
- Support different plural rules per language
```typescript
// ✅ Correct
const ItemCount = ({ count }: { count: number }) => {
const { t } = useTranslation('common');
return (
<span>{t('items.count', { count })}</span>
);
};
// Translation file
{
"items": {
"count_one": "{{count}} item",
"count_other": "{{count}} items"
}
}
```
## Translation Management
### Adding New Strings
1. Add English translation first
2. Use descriptive keys that indicate context
3. Include comments for translators when needed
4. Test with long translations to ensure UI flexibility
```json
{
"user": {
"profile": {
// Displayed in user profile header
"displayName": "Display Name",
// Used in forms when editing profile
"editDisplayName": "Edit Display Name",
// Confirmation message after profile update
"updateSuccess": "Profile updated successfully"
}
}
}
```
### Translation Validation
- Use TypeScript for translation key validation
- Implement automated checks for missing translations
- Validate interpolation parameters
```typescript
// ✅ Correct - Type-safe translations
type TranslationKey =
| 'auth.login.title'
| 'auth.login.email'
| 'auth.login.password'
| 'common.welcome.message';
const t = (key: TranslationKey, options?: any) => {
// Translation implementation
};
```
## Best Practices
### Key Naming
- Use descriptive, hierarchical keys
- Avoid abbreviations
- Group related translations
- Keep keys consistent across languages
```json
// ✅ Correct
{
"dashboard": {
"header": {
"title": "Dashboard",
"subtitle": "Welcome to your workspace"
},
"actions": {
"createNew": "Create New",
"refresh": "Refresh Data",
"export": "Export"
}
}
}
// ❌ Incorrect
{
"dash_title": "Dashboard",
"newBtn": "New",
"refreshData": "Refresh"
}
```
### String Guidelines
- Write clear, concise text
- Use consistent terminology
- Consider character limits for UI elements
- Avoid concatenating translated strings
```json
// ✅ Correct
{
"user": {
"status": {
"online": "Online",
"offline": "Offline",
"away": "Away"
}
}
}
// ❌ Incorrect - Don't concatenate
{
"user": {
"statusPrefix": "User is ",
"statusOnline": "online"
}
}
```
### Context Information
- Provide context for translators
- Include character limits when relevant
- Explain when/where text appears
- Note any technical constraints
```json
{
"button": {
// Primary action button, max 20 characters
"save": "Save Changes",
// Secondary button in modal footer
"cancel": "Cancel",
// Destructive action, should sound cautious
"delete": "Delete Permanently"
}
}
```
## Workflow
### Development Process
1. Develop features with English translations
2. Use placeholder keys during development
3. Finalize translation keys before feature completion
4. Add translations to all supported languages
5. Test with different language strings
### Translation Updates
1. Create translation tasks for new features
2. Provide context and screenshots to translators
3. Review translations for consistency
4. Test UI with translated strings
5. Update documentation when needed
### Quality Assurance
- Review translations in context
- Test with longest expected translations
- Verify formatting with interpolation
- Check for cultural appropriateness
- Ensure accessibility with screen readers
## Maintenance
### Regular Tasks
- Review and update outdated translations
- Check for unused translation keys
- Maintain consistency across languages
- Update translation documentation
- Monitor for missing translations in new features
### Tools and Automation
- Use automated translation validation
- Implement missing translation detection
- Set up continuous integration checks
- Maintain translation coverage reports
- Use translation management platforms when needed
-172
View File
@@ -1,172 +0,0 @@
# TypeScript Guidelines
## Core TypeScript Principles
Twenty enforces strict TypeScript usage to ensure type safety and maintainable code. This document outlines our TypeScript conventions and best practices.
## Type Safety
### Strict Typing
- **No 'any' type allowed**
- TypeScript strict mode enabled
- noImplicitAny enabled
```typescript
// ✅ Correct
function processUser(user: User) {
return user.name;
}
// ❌ Incorrect
function processUser(user: any) {
return user.name;
}
```
### Type Definitions
#### Types over Interfaces
- Use `type` for all type definitions
- Exception: When extending third-party interfaces
```typescript
// ✅ Correct
type User = {
id: string;
name: string;
email: string;
};
// ❌ Incorrect
interface User {
id: string;
name: string;
email: string;
}
```
### String Literals over Enums
- Use string literal unions instead of enums
- Exception: GraphQL enums
```typescript
// ✅ Correct
type UserRole = 'admin' | 'user' | 'guest';
// ❌ Incorrect
enum UserRole {
Admin = 'admin',
User = 'user',
Guest = 'guest',
}
```
## Naming Conventions
### Component Props
- Suffix component prop types with 'Props'
- Keep props focused and single-purpose
```typescript
// ✅ Correct
type ButtonProps = {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
};
// ❌ Incorrect
type ButtonParameters = {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
};
```
## Type Inference
### Leverage TypeScript Inference
- Use type inference when types are clear
- Explicitly type when inference is ambiguous
```typescript
// ✅ Correct - Clear inference
const users = ['John', 'Jane']; // inferred as string[]
// ✅ Correct - Explicit typing needed
const processUser = (user: User): UserResponse => {
// Complex processing
return response;
};
// ❌ Incorrect - Unnecessary explicit typing
const users: string[] = ['John', 'Jane'];
```
## Best Practices
### Type Guards
- Use type guards for runtime type checking
- Prefer discriminated unions
```typescript
// ✅ Correct
type Success = {
type: 'success';
data: User;
};
type Error = {
type: 'error';
message: string;
};
type Result = Success | Error;
function handleResult(result: Result) {
if (result.type === 'success') {
// TypeScript knows result.data exists
console.log(result.data);
}
}
```
### Generics
- Use generics for reusable type patterns
- Keep generic names descriptive
```typescript
// ✅ Correct
type ApiResponse<TData> = {
data: TData;
status: number;
message: string;
};
// ❌ Incorrect
type ApiResponse<T> = {
data: T;
status: number;
message: string;
};
```
### Type Exports
- Export types when they're used across files
- Keep type definitions close to their usage
```typescript
// types.ts
export type User = {
id: string;
name: string;
};
// UserComponent.tsx
import { type User } from './types';
```
### Utility Types
- Leverage TypeScript utility types
- Create custom utility types for repeated patterns
```typescript
// Built-in utility types
type UserPartial = Partial<User>;
type UserReadonly = Readonly<User>;
// Custom utility types
type NonNullableProperties<T> = {
[P in keyof T]: NonNullable<T[P]>;
};
```
+182
View File
@@ -0,0 +1,182 @@
---
description: TypeScript best practices and conventions for the Twenty codebase, including strict typing, naming conventions, and type safety guidelines.
alwaysApply: false
---
---
description: TypeScript best practices and conventions for the Twenty codebase, including strict typing, naming conventions, and type safety guidelines.
globs: ["**/*.ts", "**/*.tsx"]
alwaysApply: false
---
# TypeScript Guidelines
## Core TypeScript Principles
Twenty enforces strict TypeScript usage to ensure type safety and maintainable code. This document outlines our TypeScript conventions and best practices.
## Type Safety
### Strict Typing
- **No 'any' type allowed**
- TypeScript strict mode enabled
- noImplicitAny enabled
```typescript
// ✅ Correct
function processUser(user: User) {
return user.name;
}
// ❌ Incorrect
function processUser(user: any) {
return user.name;
}
```
### Type Definitions
#### Types over Interfaces
- Use `type` for all type definitions
- Exception: When extending third-party interfaces
```typescript
// ✅ Correct
type User = {
id: string;
name: string;
email: string;
};
// ❌ Incorrect
interface User {
id: string;
name: string;
email: string;
}
```
### String Literals over Enums
- Use string literal unions instead of enums
- Exception: GraphQL enums
```typescript
// ✅ Correct
type UserRole = 'admin' | 'user' | 'guest';
// ❌ Incorrect
enum UserRole {
Admin = 'admin',
User = 'user',
Guest = 'guest',
}
```
## Naming Conventions
### Component Props
- Suffix component prop types with 'Props'
- Keep props focused and single-purpose
```typescript
// ✅ Correct
type ButtonProps = {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
};
// ❌ Incorrect
type ButtonParameters = {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
};
```
## Type Inference
### Leverage TypeScript Inference
- Use type inference when types are clear
- Explicitly type when inference is ambiguous
```typescript
// ✅ Correct - Clear inference
const users = ['John', 'Jane']; // inferred as string[]
// ✅ Correct - Explicit typing needed
const processUser = (user: User): UserResponse => {
// Complex processing
return response;
};
// ❌ Incorrect - Unnecessary explicit typing
const users: string[] = ['John', 'Jane'];
```
## Best Practices
### Type Guards
- Use type guards for runtime type checking
- Prefer discriminated unions
```typescript
// ✅ Correct
type Success = {
type: 'success';
data: User;
};
type Error = {
type: 'error';
message: string;
};
type Result = Success | Error;
function handleResult(result: Result) {
if (result.type === 'success') {
// TypeScript knows result.data exists
console.log(result.data);
}
}
```
### Generics
- Use generics for reusable type patterns
- Keep generic names descriptive
```typescript
// ✅ Correct
type ApiResponse<TData> = {
data: TData;
status: number;
message: string;
};
// ❌ Incorrect
type ApiResponse<T> = {
data: T;
status: number;
message: string;
};
```
### Type Exports
- Export types when they're used across files
- Keep type definitions close to their usage
```typescript
// types.ts
export type User = {
id: string;
name: string;
};
// UserComponent.tsx
import { type User } from './types';
```
### Utility Types
- Leverage TypeScript utility types
- Create custom utility types for repeated patterns
```typescript
// Built-in utility types
type UserPartial = Partial<User>;
type UserReadonly = Readonly<User>;
// Custom utility types
type NonNullableProperties<T> = {
[P in keyof T]: NonNullable<T[P]>;
};
```
+8
View File
@@ -0,0 +1,8 @@
{
"setup-worktree": [
"nvm use",
"yarn",
"cp $ROOT_WORKTREE_PATH/packages/twenty-server/.env packages/twenty-server/.env || true",
"cp $ROOT_WORKTREE_PATH/packages/twenty-front/.env packages/twenty-front/.env || true"
]
}
+1
View File
@@ -2,3 +2,4 @@
.env
node_modules
.nx/cache
packages/twenty-server/.env
-148
View File
@@ -1,148 +0,0 @@
module.exports = {
root: true,
extends: ['plugin:prettier/recommended', 'plugin:lingui/recommended'],
plugins: [
'@nx',
'prefer-arrow',
'import',
'unused-imports',
'unicorn',
'lingui',
],
rules: {
'lingui/no-single-variables-to-translate': 'off',
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'no-console': ['warn', { allow: ['group', 'groupCollapsed', 'groupEnd'] }],
'no-control-regex': 0,
'no-debugger': 'error',
'no-duplicate-imports': 'error',
'no-undef': 'off',
'no-unused-vars': 'off',
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: [],
depConstraints: [
{
sourceTag: 'scope:shared',
onlyDependOnLibsWithTags: ['scope:shared'],
},
{
sourceTag: 'scope:backend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:backend'],
},
{
sourceTag: 'scope:frontend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:frontend'],
},
{
sourceTag: 'scope:zapier',
onlyDependOnLibsWithTags: ['scope:shared'],
},
],
},
],
'import/no-relative-packages': 'error',
'import/no-useless-path-segments': 'error',
'import/no-duplicates': ['error', { considerQueryString: true }],
'prefer-arrow/prefer-arrow-functions': [
'error',
{
disallowPrototype: true,
singleReturnOnly: false,
classPropertiesAllowed: false,
},
],
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
},
overrides: [
{
files: ['**/*.ts', '**/*.tsx'],
extends: ['plugin:@nx/typescript'],
rules: {
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/consistent-type-imports': [
'error',
{ prefer: 'no-type-imports' },
],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/no-empty-interface': [
'error',
{
allowSingleExtends: true,
},
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
},
},
{
files: ['*.js', '*.jsx'],
extends: ['plugin:@nx/javascript'],
rules: {},
},
{
files: [
'*.spec.@(ts|tsx|js|jsx)',
'*.integration-spec.@(ts|tsx|js|jsx)',
'*.test.@(ts|tsx|js|jsx)',
],
env: {
jest: true,
},
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
{
files: ['**/constants/*.ts', '**/*.constants.ts'],
rules: {
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['UPPER_CASE'],
},
],
'unicorn/filename-case': [
'warn',
{
cases: {
pascalCase: true,
},
},
],
'@nx/workspace-max-consts-per-file': ['error', { max: 1 }],
},
},
{
files: ['*.json'],
parser: 'jsonc-eslint-parser',
},
],
};
-90
View File
@@ -1,90 +0,0 @@
var path = require('path');
module.exports = {
extends: [
'plugin:@nx/react',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:storybook/recommended',
],
plugins: ['react-hooks', 'react-refresh'],
overrides: [
{
files: ['*.ts', '*.tsx'],
parserOptions: {
project: ['./tsconfig.base.{json,*.json}'],
},
rules: {
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['@tabler/icons-react'],
message: 'Please import icons from `twenty-ui`',
},
{
group: ['react-hotkeys-web-hook'],
importNames: ['useHotkeys'],
message:
'Please use the custom wrapper: `useScopedHotkeys` from `twenty-ui`',
},
{
group: ['lodash'],
message:
"Please use the standalone lodash package (for instance: `import groupBy from 'lodash.groupby'` instead of `import { groupBy } from 'lodash'`)",
},
],
},
],
'@nx/workspace-effect-components': 'error',
'@nx/workspace-no-hardcoded-colors': 'error',
'@nx/workspace-matching-state-variable': 'error',
'@nx/workspace-sort-css-properties-alphabetically': 'error',
'@nx/workspace-styled-components-prefixed-with-styled': 'error',
'@nx/workspace-no-state-useref': 'error',
'@nx/workspace-component-props-naming': 'error',
'@nx/workspace-explicit-boolean-predicates-in-if': 'error',
'@nx/workspace-use-getLoadable-and-getValue-to-get-atoms': 'error',
'@nx/workspace-useRecoilCallback-has-dependency-array': 'error',
'@nx/workspace-no-navigate-prefer-link': 'error',
'react/no-unescaped-entities': 'off',
'react/prop-types': 'off',
'react/jsx-key': 'off',
'react/display-name': 'off',
'react/jsx-uses-react': 'off',
'react/react-in-jsx-scope': 'off',
'react/jsx-no-useless-fragment': 'off',
'react/jsx-props-no-spreading': [
'error',
{
explicitSpread: 'ignore',
},
],
'react-hooks/exhaustive-deps': [
'warn',
{
additionalHooks: 'useRecoilCallback',
},
],
},
},
{
files: ['*.stories.@(ts|tsx|js|jsx)'],
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
{
files: ['.storybook/main.@(js|cjs|mjs|ts)'],
rules: {
'storybook/no-uninstalled-addons': [
'error',
{
packageJsonLocation: path.resolve(__dirname, './package.json'),
},
],
},
},
],
};
+28
View File
@@ -0,0 +1,28 @@
* text=auto eol=lf
*.ts text eol=lf
*.tsx text eol=lf
*.js text eol=lf
*.jsx text eol=lf
*.json text eol=lf
*.md text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.sh text eol=lf
*.mjs text eol=lf
*.cjs text eol=lf
# Patch files may have mixed line endings by design
*.patch -text
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.svg binary
*.woff binary
*.woff2 binary
*.ttf binary
*.eot binary
+6 -10
View File
@@ -1,26 +1,22 @@
# Contributing to Twenty
Thanks for considering contributing to Twenty!
Thanks for considering contributing to Twenty!
Please make sure to go through the [documentation](https://docs.twenty.com) before.
Please make sure to go through the [documentation](https://docs.twenty.com) before.
<br>
## Good first issues
Good first issues are a great way to start contributing and get familiar with the codebase. You can find them on by filtering on the [good first issue](https://github.com/twentyhq/twenty/labels/good%20first%20issue) label.
Good first issues are a great way to start contributing and get familiar with the codebase. You can find them on by filtering on the [good first issue](https://github.com/twentyhq/twenty/labels/good%20first%20issue) label.
## Issue assignment
Having multiple contributors address the same issue can cause frustration.
To avoid conflicts, we follow these guidelines:
1. If a core team member assigned you the issue within the last three days, your PR takes priority.
2. Otherwise, the first submitted PR is prioritized.
3. For "size: long" PRs, the assignment period extends to one week.
Please ensure you're assigned to an issue before starting work.
1. For `Good First Issue` and `Experienced Contributor` issues without `size: long` labels, we'll merge the first PRs that meet our [code quality standards](https://docs.twenty.com/developers). **We don't assign contributors to these issues**. For `priority: high` issues, our core team will step in within days if no adequate contributions are received.
2. For `size: long` Issues, assigned contributors have one week to submit their first draft PR.
## How to Contribute
@@ -67,4 +63,4 @@ git push origin your-branch-name
## Reporting Issues
If you face any issues or have suggestions, please feel free to (create an issue on Twenty's GitHub repository)[https://github.com/twentyhq/twenty/issues/new]. Please provide as much detail as possible.
If you face any issues or have suggestions, please feel free to (create an issue on Twenty's GitHub repository)[https://github.com/twentyhq/twenty/issues/new]. Please provide as much detail as possible.
@@ -27,7 +27,7 @@ Having a list that is draggable will be useful, not only in dropdown.
Create a folder @/ui/draggable-list with a DraggableList component
This component should take as prop: itemsComponents, onDragEnd((previousIndex, nextIndex) => {})
Use this component in ViewFieldsVisibilityDropdownSection (move the logic from ViewFieldsVisibilityDropdownSection to DraggableList) by passing a list of DraggableMenuItems
Use this component in ObjectOptionsDropdownHiddenFieldsContent (move the logic from ObjectOptionsDropdownHiddenFieldsContent to DraggableList) by passing a list of DraggableMenuItems
Add a storybook test on this list (we don't know how to actually test the draggable behavior, but we can at least make sure the component renders correctly a list of items)
```
+15
View File
@@ -0,0 +1,15 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 3
versioning-strategy: "lockfile-only"
assignees:
- "mabdullahabaid"
ignore:
- dependency-name: "@graphql-yoga/nestjs"
- dependency-name: "@nestjs/graphql"
- dependency-name: "@ptc-org/nestjs-query-graphql"
- dependency-name: "typeorm"
@@ -10,7 +10,8 @@ inputs:
configuration:
required: false
default: 'ci'
args:
required: false
runs:
using: "composite"
steps:
@@ -18,4 +19,4 @@ runs:
uses: nrwl/nx-set-shas@v4
- name: Run affected command
shell: bash
run: npx nx affected --nxBail --configuration=${{ inputs.configuration }} -t=${{ inputs.tasks }} --parallel=${{ inputs.parallel }} --exclude='*,!tag:${{ inputs.tag }}'
run: npx nx affected --nxBail --configuration=${{ inputs.configuration }} -t=${{ inputs.tasks }} --parallel=${{ inputs.parallel }} --exclude='*,!tag:${{ inputs.tag }}' ${{ inputs.args }}
@@ -20,16 +20,16 @@ runs:
id: cache-primary-key-builder
shell: bash
run: |
echo "CACHE_PRIMARY_KEY_PREFIX=v2-${{ inputs.key }}-${{ github.ref_name }}" >> "${GITHUB_OUTPUT}"
echo "CACHE_PRIMARY_KEY_PREFIX=v3-${{ inputs.key }}-${{ github.ref_name }}" >> "${GITHUB_OUTPUT}"
- name: Restore cache
uses: actions/cache/restore@v4
id: restore-cache
with:
key: ${{ steps.cache-primary-key-builder.outputs.CACHE_PRIMARY_KEY_PREFIX }}-${{ github.sha }}
key: ${{ steps.cache-primary-key-builder.outputs.CACHE_PRIMARY_KEY_PREFIX }}-${{ github.sha }}
restore-keys: ${{ steps.cache-primary-key-builder.outputs.CACHE_PRIMARY_KEY_PREFIX }}-
path: |
.cache
.nx/cache
.nx
node_modules/.cache
packages/*/node_modules/.cache
${{ inputs.additional-paths }}
@@ -15,7 +15,7 @@ runs:
key: ${{ inputs.key }}
path: |
.cache
.nx/cache
.nx
node_modules/.cache
packages/*/node_modules/.cache
${{ inputs.additional-paths }}
@@ -2,10 +2,10 @@ name: Yarn Install
inputs:
node-version:
required: false
default: '18'
default: '24'
runs:
using: "composite"
using: 'composite'
steps:
- name: Cache primary key builder
id: globals
@@ -25,8 +25,8 @@ runs:
id: cache-node-modules
uses: actions/cache/restore@v4
with:
key: v2-${{ steps.globals.outputs.CACHE_KEY_PREFIX }}-${{github.sha}}
restore-keys: v2-${{ steps.globals.outputs.CACHE_KEY_PREFIX }}-
key: v4-${{ steps.globals.outputs.CACHE_KEY_PREFIX }}-${{github.sha}}
restore-keys: v4-${{ steps.globals.outputs.CACHE_KEY_PREFIX }}-
path: ${{ steps.globals.outputs.PATH_TO_CACHE }}
- name: Install Dependencies
if: ${{ steps.cache-node-modules.outputs.cache-hit != 'true' && steps.cache-node-modules.outputs.cache-matched-key == '' }}
@@ -40,4 +40,3 @@ runs:
with:
key: ${{ steps.cache-node-modules.outputs.cache-primary-key }}
path: ${{ steps.globals.outputs.PATH_TO_CACHE }}
+5
View File
@@ -1,8 +1,13 @@
name: CD deploy main
permissions:
contents: read
on:
push:
branches:
- main
jobs:
deploy-main:
timeout-minutes: 3
+5
View File
@@ -1,8 +1,13 @@
name: CD deploy tag
permissions:
contents: read
on:
push:
tags:
- 'v*'
jobs:
deploy-tag:
timeout-minutes: 3
+4
View File
@@ -1,4 +1,5 @@
name: Changed files reusable workflow
on:
workflow_call:
inputs:
@@ -9,6 +10,9 @@ on:
any_changed:
value: ${{ jobs.changed-files.outputs.any_changed }}
permissions:
contents: read
jobs:
changed-files:
timeout-minutes: 5
+786
View File
@@ -0,0 +1,786 @@
name: GraphQL and OpenAPI Breaking Changes Detection
on:
pull_request:
types: [opened, synchronize, edited]
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
env:
MAIN_SERVER_PORT: 3000
CURRENT_SERVER_PORT: 3002
permissions:
contents: read
pull-requests: write
checks: write
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
package.json
packages/twenty-server/**
packages/twenty-emails/**
packages/twenty-shared/**
.github/workflows/ci-breaking-changes.yaml
api-breaking-changes:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 45
runs-on: ubuntu-latest
services:
postgres:
image: twentycrm/twenty-postgres-spilo
env:
PGUSER_SUPERUSER: postgres
PGPASSWORD_SUPERUSER: postgres
ALLOW_NOSSL: 'true'
SPILO_PROVIDER: 'local'
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis
ports:
- 6379:6379
clickhouse:
image: clickhouse/clickhouse-server:25.8.8
env:
CLICKHOUSE_PASSWORD: clickhousePassword
CLICKHOUSE_URL: "http://default:clickhousePassword@localhost:8123/twenty"
ports:
- 8123:8123
- 9000:9000
options: >-
--health-cmd "clickhouse-client --host=localhost --port=9000 --user=default --password=clickhousePassword --query='SELECT 1'"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout current branch
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Try to merge main into current branch
id: merge_attempt
run: |
echo "Attempting to merge main into current branch..."
git fetch origin main
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo "Current branch: $CURRENT_BRANCH"
if git merge origin/main --no-edit; then
echo "✅ Successfully merged main into current branch"
echo "merged=true" >> $GITHUB_OUTPUT
echo "BRANCH_STATE=merged" >> $GITHUB_ENV
else
echo "❌ Merge failed due to conflicts"
echo "⚠️ Falling back to comparing current branch against main without merge"
# Abort the failed merge
git merge --abort
echo "merged=false" >> $GITHUB_OUTPUT
echo "BRANCH_STATE=conflicts" >> $GITHUB_ENV
fi
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Build shared dependencies
run: |
npx nx build twenty-shared
npx nx build twenty-emails
- name: Build current branch server
run: npx nx build twenty-server
- name: Setup databases
run: |
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "current_branch";'
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "main_branch";'
- name: Run ClickHouse migrations
run: npx nx clickhouse:migrate twenty-server
env:
CLICKHOUSE_URL: http://default:clickhousePassword@localhost:8123/twenty
CLICKHOUSE_PASSWORD: clickhousePassword
- name: Setup current branch database
run: |
npx nx reset:env twenty-server
set_env_var() {
local var_name="$1"
local var_value="$2"
local env_file="packages/twenty-server/.env"
echo "" >> "$env_file"
if grep -q "^${var_name}=" "$env_file" 2>/dev/null; then
sed -i "s|^${var_name}=.*|${var_name}=${var_value}|" "$env_file"
else
echo "${var_name}=${var_value}" >> "$env_file"
fi
}
set_env_var "PG_DATABASE_URL" "postgres://postgres:postgres@localhost:5432/current_branch"
set_env_var "NODE_PORT" "${{ env.CURRENT_SERVER_PORT }}"
set_env_var "REDIS_URL" "redis://localhost:6379"
set_env_var "CLICKHOUSE_URL" "http://default:clickhousePassword@localhost:8123/twenty"
set_env_var "CLICKHOUSE_PASSWORD" "clickhousePassword"
npx nx run twenty-server:database:init:prod
npx nx run twenty-server:database:migrate:prod
- name: Seed current branch database with test data
run: |
npx nx command-no-deps twenty-server -- workspace:seed:dev
- name: Start current branch server in background
run: |
echo "=== Current branch .env file contents ==="
cat packages/twenty-server/.env
echo "=== Starting current branch server ==="
nohup npx nx run twenty-server:start:prod > /tmp/current-server.log 2>&1 &
echo $! > /tmp/current-server.pid
echo "Current server PID: $(cat /tmp/current-server.pid)"
- name: Wait for current branch server to be ready
run: |
echo "Waiting for current branch server to start..."
timeout=300
interval=5
elapsed=0
while [ $elapsed -lt $timeout ]; do
if curl -s "http://localhost:${{ env.CURRENT_SERVER_PORT }}/graphql" > /dev/null 2>&1 && \
curl -s "http://localhost:${{ env.CURRENT_SERVER_PORT }}/rest/open-api/core" > /dev/null 2>&1; then
echo "Current branch server is ready!"
break
fi
echo "Current branch server not ready yet, waiting ${interval}s..."
sleep $interval
elapsed=$((elapsed + interval))
done
if [ $elapsed -ge $timeout ]; then
echo "Timeout waiting for current branch server to start"
echo "Current server log:"
cat /tmp/current-server.log || echo "No current server log found"
exit 1
fi
- name: Download GraphQL and REST responses from current branch
run: |
# Admin token from jest-integration.config.ts
ADMIN_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC05ZTNiLTQ2ZDQtYTU1Ni04OGI5ZGRjMmIwMzQiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtMDY4Ny00YzQxLWI3MDctZWQxYmZjYTk3MmE3IiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtOWUzYi00NmQ0LWE1NTYtODhiOWRkYzJiMDM1IiwiaWF0IjoxNzM5NTQ3NjYxLCJleHAiOjMzMjk3MTQ3NjYxfQ.fbOM9yhr3jWDicPZ1n771usUURiPGmNdeFApsgrbxOw"
# Load introspection query from file
INTROSPECTION_QUERY=$(cat packages/twenty-utils/graphql-introspection-query.graphql)
# Prepare the query payload
QUERY_PAYLOAD=$(echo "$INTROSPECTION_QUERY" | tr '\n' ' ' | sed 's/"/\\"/g')
echo "Downloading GraphQL schema from current server..."
curl -X POST "http://localhost:${{ env.CURRENT_SERVER_PORT }}/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
-d "{\"query\":\"${QUERY_PAYLOAD}\"}" \
-o current-schema-introspection.json \
-w "HTTP Status: %{http_code}\n" \
-s
echo "Downloading GraphQL metadata schema from current server..."
curl -X POST "http://localhost:${{ env.CURRENT_SERVER_PORT }}/metadata" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
-d "{\"query\":\"${QUERY_PAYLOAD}\"}" \
-o current-metadata-schema-introspection.json \
-w "HTTP Status: %{http_code}\n" \
-s
# Download current branch OpenAPI specs
echo "Downloading OpenAPI specifications from current server..."
curl -s "http://localhost:${{ env.CURRENT_SERVER_PORT }}/rest/open-api/core" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
-o current-rest-api.json \
-w "HTTP Status: %{http_code}\n"
curl -s "http://localhost:${{ env.CURRENT_SERVER_PORT }}/rest/open-api/metadata" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
-o current-rest-metadata-api.json \
-w "HTTP Status: %{http_code}\n"
# Verify the downloads
echo "Current branch files downloaded:"
ls -la current-*
- name: Preserve current branch files
run: |
# Create a temp directory to store current branch files
mkdir -p /tmp/current-branch-files
# Move current branch files to temp directory
mv current-* /tmp/current-branch-files/ 2>/dev/null || echo "No current-* files to preserve"
echo "Preserved current branch files for later restoration"
- name: Stop current branch server
run: |
if [ -f /tmp/current-server.pid ]; then
echo "Stopping current branch server..."
kill $(cat /tmp/current-server.pid) || true
# Wait a bit for graceful shutdown
sleep 5
# Force kill if still running
kill -9 $(cat /tmp/current-server.pid) 2>/dev/null || true
rm -f /tmp/current-server.pid
fi
- name: Checkout main branch
run: |
git stash
git checkout origin/main
git reset --hard
git clean -xfd -ff
rm -rf node_modules packages/*/node_modules packages/*/dist dist .nx/cache
- name: Install dependencies for main branch
uses: ./.github/workflows/actions/yarn-install
- name: Build main branch dependencies
run: |
npx nx reset
npx nx build twenty-shared
npx nx build twenty-emails
- name: Build main branch server
run: npx nx build twenty-server
- name: Setup main branch database
run: |
npx nx reset:env twenty-server
set_env_var() {
local var_name="$1"
local var_value="$2"
local env_file="packages/twenty-server/.env"
echo "" >> "$env_file"
if grep -q "^${var_name}=" "$env_file" 2>/dev/null; then
sed -i "s|^${var_name}=.*|${var_name}=${var_value}|" "$env_file"
else
echo "${var_name}=${var_value}" >> "$env_file"
fi
}
set_env_var "PG_DATABASE_URL" "postgres://postgres:postgres@localhost:5432/main_branch"
set_env_var "NODE_PORT" "${{ env.MAIN_SERVER_PORT }}"
set_env_var "REDIS_URL" "redis://localhost:6379"
set_env_var "CLICKHOUSE_URL" "http://default:clickhousePassword@localhost:8123/twenty"
set_env_var "CLICKHOUSE_PASSWORD" "clickhousePassword"
npx nx run twenty-server:database:init:prod
npx nx run twenty-server:database:migrate:prod
- name: Seed main branch database with test data
run: |
npx nx command-no-deps twenty-server -- workspace:seed:dev
- name: Start main branch server in background
run: |
echo "=== Main branch .env file contents ==="
cat packages/twenty-server/.env
echo "=== Starting main branch server ==="
nohup npx nx run twenty-server:start:prod > /tmp/main-server.log 2>&1 &
echo $! > /tmp/main-server.pid
echo "Main server PID: $(cat /tmp/main-server.pid)"
- name: Wait for main branch server to be ready
run: |
echo "Waiting for main branch server to start..."
timeout=300
interval=5
elapsed=0
while [ $elapsed -lt $timeout ]; do
if curl -s "http://localhost:${{ env.MAIN_SERVER_PORT }}/graphql" > /dev/null 2>&1 && \
curl -s "http://localhost:${{ env.MAIN_SERVER_PORT }}/rest/open-api/core" > /dev/null 2>&1; then
echo "Main branch server is ready!"
break
fi
echo "Main branch server not ready yet, waiting ${interval}s..."
sleep $interval
elapsed=$((elapsed + interval))
done
if [ $elapsed -ge $timeout ]; then
echo "Timeout waiting for main branch server to start"
echo "Main server log:"
cat /tmp/main-server.log || echo "No main server log found"
exit 1
fi
- name: Download GraphQL and REST responses from main branch
run: |
# Admin token from jest-integration.config.ts
ADMIN_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC05ZTNiLTQ2ZDQtYTU1Ni04OGI5ZGRjMmIwMzQiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtMDY4Ny00YzQxLWI3MDctZWQxYmZjYTk3MmE3IiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtOWUzYi00NmQ0LWE1NTYtODhiOWRkYzJiMDM1IiwiaWF0IjoxNzM5NTQ3NjYxLCJleHAiOjMzMjk3MTQ3NjYxfQ.fbOM9yhr3jWDicPZ1n771usUURiPGmNdeFApsgrbxOw"
# Load introspection query from file
INTROSPECTION_QUERY=$(cat packages/twenty-utils/graphql-introspection-query.graphql)
# Prepare the query payload
QUERY_PAYLOAD=$(echo "$INTROSPECTION_QUERY" | tr '\n' ' ' | sed 's/"/\\"/g')
echo "Downloading GraphQL schema from main server..."
curl -X POST "http://localhost:${{ env.MAIN_SERVER_PORT }}/graphql" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
-d "{\"query\":\"${QUERY_PAYLOAD}\"}" \
-o main-schema-introspection.json \
-w "HTTP Status: %{http_code}\n" \
-s
echo "Downloading GraphQL metadata schema from main server..."
curl -X POST "http://localhost:${{ env.MAIN_SERVER_PORT }}/metadata" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
-d "{\"query\":\"${QUERY_PAYLOAD}\"}" \
-o main-metadata-schema-introspection.json \
-w "HTTP Status: %{http_code}\n" \
-s
# Download main branch OpenAPI specs
echo "Downloading OpenAPI specifications from main server..."
curl -s "http://localhost:${{ env.MAIN_SERVER_PORT }}/rest/open-api/core" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
-o main-rest-api.json \
-w "HTTP Status: %{http_code}\n"
curl -s "http://localhost:${{ env.MAIN_SERVER_PORT }}/rest/open-api/metadata" \
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
-o main-rest-metadata-api.json \
-w "HTTP Status: %{http_code}\n"
# Verify the downloads
echo "Main branch files downloaded:"
ls -la main-*
- name: Restore current branch files
run: |
# Move current branch files back to working directory
mv /tmp/current-branch-files/* . 2>/dev/null || echo "No files to restore"
# Verify all files are present
echo "All API files restored:"
ls -la current-* main-* 2>/dev/null || echo "Some files may be missing"
# Clean up temp directory
rm -rf /tmp/current-branch-files
- name: Install OpenAPI Diff Tool
run: |
# Using the Java-based OpenAPITools/openapi-diff via Docker
echo "Using OpenAPITools/openapi-diff via Docker"
- name: Generate GraphQL Schema Diff Reports
run: |
echo "=== INSTALLING GRAPHQL INSPECTOR CLI ==="
npm install -g @graphql-inspector/cli
echo "=== GENERATING GRAPHQL DIFF REPORTS ==="
# Check if GraphQL schema has changes
echo "Checking GraphQL schema for changes..."
if graphql-inspector diff main-schema-introspection.json current-schema-introspection.json >/dev/null 2>&1; then
echo "✅ No changes in GraphQL schema"
# Don't create a diff file for no changes
else
echo "⚠️ Changes detected in GraphQL schema, generating report..."
echo "# GraphQL Schema Changes" > graphql-schema-diff.md
echo "" >> graphql-schema-diff.md
graphql-inspector diff main-schema-introspection.json current-schema-introspection.json >> graphql-schema-diff.md 2>&1 || {
echo "⚠️ **Breaking changes or errors detected in GraphQL schema**" >> graphql-schema-diff.md
echo "" >> graphql-schema-diff.md
echo "\`\`\`" >> graphql-schema-diff.md
graphql-inspector diff main-schema-introspection.json current-schema-introspection.json 2>&1 >> graphql-schema-diff.md || echo "Error generating diff" >> graphql-schema-diff.md
echo "\`\`\`" >> graphql-schema-diff.md
}
fi
# Check if GraphQL metadata schema has changes
echo "Checking GraphQL metadata schema for changes..."
if graphql-inspector diff main-metadata-schema-introspection.json current-metadata-schema-introspection.json >/dev/null 2>&1; then
echo "✅ No changes in GraphQL metadata schema"
# Don't create a diff file for no changes
else
echo "⚠️ Changes detected in GraphQL metadata schema, generating report..."
echo "# GraphQL Metadata Schema Changes" > graphql-metadata-diff.md
echo "" >> graphql-metadata-diff.md
graphql-inspector diff main-metadata-schema-introspection.json current-metadata-schema-introspection.json >> graphql-metadata-diff.md 2>&1 || {
echo "⚠️ **Breaking changes or errors detected in GraphQL metadata schema**" >> graphql-metadata-diff.md
echo "" >> graphql-metadata-diff.md
echo "\`\`\`" >> graphql-metadata-diff.md
graphql-inspector diff main-metadata-schema-introspection.json current-metadata-schema-introspection.json 2>&1 >> graphql-metadata-diff.md || echo "Error generating diff" >> graphql-metadata-diff.md
echo "\`\`\`" >> graphql-metadata-diff.md
}
fi
# Show summary
echo "Generated diff files:"
ls -la *-diff.md 2>/dev/null || echo "No diff files generated (no changes detected)"
- name: Check REST API Breaking Changes
run: |
echo "=== CHECKING REST API FOR BREAKING CHANGES ==="
# Use the Java-based openapi-diff via Docker
docker run --rm -v "$(pwd):/specs" openapitools/openapi-diff:latest \
--json /specs/rest-api-diff.json \
/specs/main-rest-api.json /specs/current-rest-api.json || echo "OpenAPI diff completed with exit code $?"
# Check if the output file was created and is valid JSON
if [ -f "rest-api-diff.json" ] && jq empty rest-api-diff.json 2>/dev/null; then
# Check for breaking changes using Java openapi-diff JSON structure
incompatible=$(jq -r '.incompatible // false' rest-api-diff.json)
different=$(jq -r '.different // false' rest-api-diff.json)
# Count changes
new_endpoints=$(jq -r '.newEndpoints | length' rest-api-diff.json 2>/dev/null || echo "0")
missing_endpoints=$(jq -r '.missingEndpoints | length' rest-api-diff.json 2>/dev/null || echo "0")
changed_operations=$(jq -r '.changedOperations | length' rest-api-diff.json 2>/dev/null || echo "0")
if [ "$incompatible" = "true" ]; then
echo "❌ Breaking changes detected in REST API"
# Generate breaking changes report
echo "# REST API Breaking Changes" > rest-api-diff.md
echo "" >> rest-api-diff.md
echo "⚠️ **Breaking changes detected that may affect existing API consumers**" >> rest-api-diff.md
echo "" >> rest-api-diff.md
# Parse and format the changes from Java openapi-diff
jq -r '
if (.missingEndpoints | length) > 0 then
"## 🚨 Removed Endpoints (" + (.missingEndpoints | length | tostring) + ")\n" +
(.missingEndpoints | map("- **" + .method + " " + .pathUrl + "**: " + (.summary // "")) | join("\n"))
else "" end,
if (.changedOperations | length) > 0 then
"\n## ⚠️ Changed Operations (" + (.changedOperations | length | tostring) + ")\n" +
(.changedOperations | map("- **" + .method + " " + .pathUrl + "**: " + (.summary // "Modified operation")) | join("\n"))
else "" end,
if (.newEndpoints | length) > 0 then
"\n## ✅ New Endpoints (" + (.newEndpoints | length | tostring) + ")\n" +
(.newEndpoints | map("- " + .method + " " + .pathUrl + ": " + (.summary // "")) | join("\n"))
else "" end
' rest-api-diff.json >> rest-api-diff.md
elif [ "$different" = "true" ]; then
echo "📝 Non-breaking changes detected ($new_endpoints new endpoints, $missing_endpoints removed, $changed_operations changed) - no PR comment will be posted"
# Don't create markdown file for non-breaking changes to avoid PR comments
else
echo "✅ No changes detected in REST API"
# Don't create diff file for no changes
fi
else
echo "⚠️ OpenAPI diff tool could not process the files"
echo "# REST API Analysis Error" > rest-api-diff.md
echo "" >> rest-api-diff.md
echo "⚠️ **Error occurred while analyzing REST API changes**" >> rest-api-diff.md
echo "" >> rest-api-diff.md
echo "## Error Output" >> rest-api-diff.md
echo "\`\`\`" >> rest-api-diff.md
docker run --rm -v "$(pwd):/specs" openapitools/openapi-diff:latest /specs/main-rest-api.json /specs/current-rest-api.json 2>&1 >> rest-api-diff.md || echo "Could not capture error output"
echo "\`\`\`" >> rest-api-diff.md
# Don't fail the workflow for tool errors
echo "::warning::REST API analysis tool error - continuing workflow"
fi
- name: Check REST Metadata API Breaking Changes
run: |
echo "=== CHECKING REST METADATA API FOR BREAKING CHANGES ==="
# Use the Java-based openapi-diff for metadata API as well
docker run --rm -v "$(pwd):/specs" openapitools/openapi-diff:latest \
--json /specs/rest-metadata-api-diff.json \
/specs/main-rest-metadata-api.json /specs/current-rest-metadata-api.json || echo "OpenAPI diff completed with exit code $?"
# Check if the output file was created and is valid JSON
if [ -f "rest-metadata-api-diff.json" ] && jq empty rest-metadata-api-diff.json 2>/dev/null; then
# Check for breaking changes using Java openapi-diff JSON structure
incompatible=$(jq -r '.incompatible // false' rest-metadata-api-diff.json)
different=$(jq -r '.different // false' rest-metadata-api-diff.json)
# Count changes
new_endpoints=$(jq -r '.newEndpoints | length' rest-metadata-api-diff.json 2>/dev/null || echo "0")
missing_endpoints=$(jq -r '.missingEndpoints | length' rest-metadata-api-diff.json 2>/dev/null || echo "0")
changed_operations=$(jq -r '.changedOperations | length' rest-metadata-api-diff.json 2>/dev/null || echo "0")
if [ "$incompatible" = "true" ]; then
echo "❌ Breaking changes detected in REST Metadata API"
# Generate breaking changes report (only for breaking changes)
echo "# REST Metadata API Breaking Changes" > rest-metadata-api-diff.md
echo "" >> rest-metadata-api-diff.md
echo "⚠️ **Breaking changes detected that may affect existing API consumers**" >> rest-metadata-api-diff.md
echo "" >> rest-metadata-api-diff.md
# Parse and format the changes from Java openapi-diff
jq -r '
if (.missingEndpoints | length) > 0 then
"## 🚨 Removed Endpoints (" + (.missingEndpoints | length | tostring) + ")\n" +
(.missingEndpoints | map("- **" + .method + " " + .pathUrl + "**: " + (.summary // "")) | join("\n"))
else "" end,
if (.changedOperations | length) > 0 then
"\n## ⚠️ Changed Operations (" + (.changedOperations | length | tostring) + ")\n" +
(.changedOperations | map("- **" + .method + " " + .pathUrl + "**: " + (.summary // "Modified operation")) | join("\n"))
else "" end,
if (.newEndpoints | length) > 0 then
"\n## ✅ New Endpoints (" + (.newEndpoints | length | tostring) + ")\n" +
(.newEndpoints | map("- " + .method + " " + .pathUrl + ": " + (.summary // "")) | join("\n"))
else "" end
' rest-metadata-api-diff.json >> rest-metadata-api-diff.md
elif [ "$different" = "true" ]; then
echo "📝 Non-breaking changes detected ($new_endpoints new endpoints, $missing_endpoints removed, $changed_operations changed) - no PR comment will be posted"
# Don't create markdown file for non-breaking changes to avoid PR comments
else
echo "✅ No changes detected in REST Metadata API"
fi
else
echo "⚠️ OpenAPI diff tool could not process the metadata API files"
echo "# REST Metadata API Analysis Error" > rest-metadata-api-diff.md
echo "" >> rest-metadata-api-diff.md
echo "⚠️ **Error occurred while analyzing REST Metadata API changes**" >> rest-metadata-api-diff.md
echo "" >> rest-metadata-api-diff.md
echo "## Error Output" >> rest-metadata-api-diff.md
echo "\`\`\`" >> rest-metadata-api-diff.md
docker run --rm -v "$(pwd):/specs" openapitools/openapi-diff:latest /specs/main-rest-metadata-api.json /specs/current-rest-metadata-api.json 2>&1 >> rest-metadata-api-diff.md || echo "Could not capture error output"
echo "\`\`\`" >> rest-metadata-api-diff.md
# Don't fail the workflow for tool errors
echo "::warning::REST Metadata API analysis tool error - continuing workflow"
fi
- name: Comment API Changes on PR
if: always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
let hasChanges = false;
let comment = '';
try {
if (fs.existsSync('graphql-schema-diff.md')) {
const graphqlDiff = fs.readFileSync('graphql-schema-diff.md', 'utf8');
if (graphqlDiff.trim()) {
if (!hasChanges) {
comment = '## 📊 API Changes Report\n\n';
hasChanges = true;
}
comment += '### GraphQL Schema Changes\n' + graphqlDiff + '\n\n';
}
}
if (fs.existsSync('graphql-metadata-diff.md')) {
const graphqlMetadataDiff = fs.readFileSync('graphql-metadata-diff.md', 'utf8');
if (graphqlMetadataDiff.trim()) {
if (!hasChanges) {
comment = '## 📊 API Changes Report\n\n';
hasChanges = true;
}
comment += '### GraphQL Metadata Schema Changes\n' + graphqlMetadataDiff + '\n\n';
}
}
if (fs.existsSync('rest-api-diff.md')) {
const restDiff = fs.readFileSync('rest-api-diff.md', 'utf8');
if (restDiff.trim()) {
if (!hasChanges) {
comment = '## 📊 API Changes Report\n\n';
hasChanges = true;
}
comment += restDiff + '\n\n';
}
}
if (fs.existsSync('rest-metadata-api-diff.md')) {
const metadataDiff = fs.readFileSync('rest-metadata-api-diff.md', 'utf8');
if (metadataDiff.trim()) {
if (!hasChanges) {
comment = '## 📊 API Changes Report\n\n';
hasChanges = true;
}
comment += metadataDiff + '\n\n';
}
}
// Only post comment if there are changes
if (hasChanges) {
// Add branch state information only if there were conflicts
const branchState = process.env.BRANCH_STATE || 'unknown';
let branchStateNote = '';
if (branchState === 'conflicts') {
branchStateNote = '\n\n⚠️ **Note**: Could not merge with `main` due to conflicts. This comparison shows changes between the current branch and `main` as separate states.\n';
}
// Check if there are any breaking changes detected
let hasBreakingChanges = false;
let breakingChangeNote = '';
// Check for breaking changes in any of the diff files
if (fs.existsSync('rest-api-diff.md')) {
const restDiff = fs.readFileSync('rest-api-diff.md', 'utf8');
if (restDiff.includes('Breaking Changes') || restDiff.includes('🚨') ||
restDiff.includes('Removed Endpoints') || restDiff.includes('Changed Operations')) {
hasBreakingChanges = true;
}
}
if (fs.existsSync('rest-metadata-api-diff.md')) {
const metadataDiff = fs.readFileSync('rest-metadata-api-diff.md', 'utf8');
if (metadataDiff.includes('Breaking Changes') || metadataDiff.includes('🚨') ||
metadataDiff.includes('Removed Endpoints') || metadataDiff.includes('Changed Operations')) {
hasBreakingChanges = true;
}
}
// Also check GraphQL changes for breaking changes indicators
if (fs.existsSync('graphql-schema-diff.md')) {
const graphqlDiff = fs.readFileSync('graphql-schema-diff.md', 'utf8');
if (graphqlDiff.includes('Breaking changes') || graphqlDiff.includes('BREAKING')) {
hasBreakingChanges = true;
}
}
if (fs.existsSync('graphql-metadata-diff.md')) {
const graphqlMetadataDiff = fs.readFileSync('graphql-metadata-diff.md', 'utf8');
if (graphqlMetadataDiff.includes('Breaking changes') || graphqlMetadataDiff.includes('BREAKING')) {
hasBreakingChanges = true;
}
}
// Check PR title for "breaking"
const prTitle = ${{ toJSON(github.event.pull_request.title) }};
const titleContainsBreaking = prTitle.toLowerCase().includes('breaking');
if (hasBreakingChanges) {
if (titleContainsBreaking) {
breakingChangeNote = '\n\n## ✅ Breaking Change Protocol\n\n' +
'**This PR title contains "breaking" and breaking changes were detected - the CI will fail as expected.**\n\n' +
'📝 **Action Required**: Please add `BREAKING CHANGE:` to your commit message to trigger a major version bump.\n\n' +
'Example:\n```\nfeat: add new API endpoint\n\nBREAKING CHANGE: removed deprecated field from User schema\n```';
} else {
breakingChangeNote = '\n\n## ⚠️ Breaking Change Protocol\n\n' +
'**Breaking changes detected but PR title does not contain "breaking" - CI will pass but action needed.**\n\n' +
'🔄 **Options**:\n' +
'1. **If this IS a breaking change**: Add "breaking" to your PR title and add `BREAKING CHANGE:` to your commit message\n' +
'2. **If this is NOT a breaking change**: The API diff tool may have false positives - please review carefully\n\n' +
'For breaking changes, add to commit message:\n```\nfeat: add new API endpoint\n\nBREAKING CHANGE: removed deprecated field from User schema\n```';
}
}
const COMMENT_MARKER = '<!-- API_CHANGES_REPORT -->';
const commentBody = COMMENT_MARKER + '\n' + comment + branchStateNote + '\n⚠️ **Please review these API changes carefully before merging.**' + breakingChangeNote;
// Get all comments to find existing API changes comment
const {data: comments} = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
// Find our existing comment
const botComment = comments.find(comment => comment.body.includes(COMMENT_MARKER));
if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
});
console.log('Updated existing API changes comment');
} else {
// Create new comment
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
});
console.log('Created new API changes comment');
}
} else {
console.log('No API changes detected - skipping PR comment');
// Check if there's an existing comment to remove
const {data: comments} = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const COMMENT_MARKER = '<!-- API_CHANGES_REPORT -->';
const botComment = comments.find(comment => comment.body.includes(COMMENT_MARKER));
if (botComment) {
await github.rest.issues.deleteComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
});
console.log('Deleted existing API changes comment (no changes detected)');
}
}
} catch (error) {
console.log('Could not post comment:', error);
}
- name: Cleanup servers
if: always()
run: |
if [ -f /tmp/current-server.pid ]; then
kill $(cat /tmp/current-server.pid) || true
fi
if [ -f /tmp/main-server.pid ]; then
kill $(cat /tmp/main-server.pid) || true
fi
- name: Upload API specifications and diffs
if: always()
uses: actions/upload-artifact@v4
with:
name: api-specifications-and-diffs
path: |
/tmp/main-server.log
/tmp/current-server.log
*-api.json
*-schema-introspection.json
*-diff.md
*-diff.json
@@ -1,48 +0,0 @@
name: CI Chrome Extension
on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
package.json
packages/twenty-chrome-extension/**
chrome-extension-build:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 15
runs-on: ubuntu-latest
env:
VITE_SERVER_BASE_URL: http://localhost:3000
VITE_FRONT_BASE_URL: http://localhost:3001
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Chrome Extension / Run build
run: npx nx build twenty-chrome-extension
ci-chrome-extension-status-check:
if: always() && !cancelled()
timeout-minutes: 1
runs-on: ubuntu-latest
needs: [changed-files-check, chrome-extension-build]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
+103
View File
@@ -0,0 +1,103 @@
name: CI CLI
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
packages/twenty-cli/**
packages/twenty-server/**
cli-test:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
strategy:
matrix:
task: [lint, typecheck, test, build]
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Run ${{ matrix.task }} task
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:cli
tasks: ${{ matrix.task }}
cli-e2e-test:
timeout-minutes: 30
runs-on: depot-ubuntu-24.04-8
needs: [changed-files-check, cli-test]
if: needs.changed-files-check.outputs.any_changed == 'true'
services:
postgres:
image: twentycrm/twenty-postgres-spilo
env:
PGUSER_SUPERUSER: postgres
PGPASSWORD_SUPERUSER: postgres
ALLOW_NOSSL: 'true'
SPILO_PROVIDER: 'local'
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis
ports:
- 6379:6379
env:
NODE_ENV: test
steps:
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Server / Append billing config to .env.test
working-directory: packages/twenty-server
run: |
echo "" >> .env.test
echo "IS_BILLING_ENABLED=true" >> .env.test
echo "BILLING_STRIPE_API_KEY=test-api-key" >> .env.test
echo "BILLING_STRIPE_BASE_PLAN_PRODUCT_ID=test-base-plan-product-id" >> .env.test
echo "BILLING_STRIPE_WEBHOOK_SECRET=test-webhook-secret" >> .env.test
echo "BILLING_PLAN_REQUIRED_LINK=http://localhost:3001/stripe-redirection" >> .env.test
- name: Server / Create Test DB
run: |
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "test";'
- name: CLI / Run E2E Tests
run: npx nx test:e2e twenty-cli
ci-cli-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, cli-test, cli-e2e-test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
-63
View File
@@ -1,63 +0,0 @@
name: CI Demo check
on:
schedule:
- cron: '30 7,19 * * *'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
timeout-minutes: 15
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./packages/twenty-e2e-testing
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Install Playwright Browsers
run: yarn playwright install --with-deps
- name: Run Playwright tests
id: test
run: yarn playwright test --grep "@demo-only"
- name: Upload report after tests
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 90
- name: Send Discord notification
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
uses: Ilshidur/action-discord@0.3.2
with:
args: 'Demo check ${{ steps.test.outcome }} - check ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
- name: Send email if demo is not working
if: steps.test.outcome == 'failure'
uses: dawidd6/action-send-mail@v3.12.0
with:
connection_url: ${{ secrets.MAIL_CONNECTION }}
server_address: smtp.gmail.com
server_port: 465
secure: true
username: ${{ secrets.MAIL_USERNAME }}
subject: 'Demo is not working'
from: 'Github CI Demo check'
to: ${{ secrets.RECIPIENTS }}
body: '<a href="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}">Link</a>'
priority: high
+47
View File
@@ -0,0 +1,47 @@
name: CI Docs
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
package.json
packages/twenty-docs/**
eslint.config.mjs
docs-lint:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
with:
access_token: ${{ github.token }}
- name: Fetch local actions
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Docs / Lint English MDX files
run: npx eslint "packages/twenty-docs/{developers,user-guide,twenty-ui,getting-started,snippets}/**/*.mdx" --max-warnings 0
+6 -3
View File
@@ -1,4 +1,5 @@
name: CI E2E Playwright Tests
on:
push:
branches:
@@ -6,9 +7,12 @@ on:
pull_request:
types: [opened, synchronize, reopened, labeled]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
changed-files-check:
@@ -24,7 +28,6 @@ jobs:
if: needs.changed-files-check.outputs.any_changed == 'true' && ( github.event_name == 'push' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-e2e')))
timeout-minutes: 30
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
# https://github.com/actions/runner-images/issues/70#issuecomment-589562148
NODE_OPTIONS: "--max-old-space-size=10240"
services:
@@ -124,7 +127,7 @@ jobs:
retention-days: 30
ci-e2e-status-check:
if: always() && !cancelled()
timeout-minutes: 1
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, test]
steps:
+64
View File
@@ -0,0 +1,64 @@
name: CI Emails
permissions:
contents: read
on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
changed-files-check:
uses: ./.github/workflows/changed-files.yaml
with:
files: |
package.json
packages/twenty-emails/**
emails-test:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 10
runs-on: depot-ubuntu-24.04-8
steps:
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Build twenty-emails
run: npx nx build twenty-emails
- name: Run email tests
run: |
# Start the email server in the background
npx nx run twenty-emails:start &
SERVER_PID=$!
# Wait for server to start
sleep 20
# Check if server is running
if ! curl -s http://localhost:4001/preview/test.email > /dev/null; then
echo "Email server failed to start"
kill $SERVER_PID
exit 1
fi
# Kill the server
kill $SERVER_PID
ci-emails-status-check:
if: always() && !cancelled()
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, emails-test]
steps:
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
+17 -19
View File
@@ -1,4 +1,5 @@
name: CI Front
on:
push:
branches:
@@ -6,12 +7,16 @@ on:
pull_request:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
env:
STORYBOOK_BUILD_CACHE_KEY: storybook-build-depot-ubuntu-24.04-8-runner
STORYBOOK_BUILD_CACHE_KEY_FOR_RESTORE_ACTION: storybook-build-depot-ubuntu-24.04-8-runner
STORYBOOK_BUILD_CACHE_KEY_FOR_SAVE_ACTION: v3-storybook-build-depot-ubuntu-24.04-8-runner-${{ github.ref_name }}-${{ github.sha }}
jobs:
changed-files-check:
@@ -19,17 +24,17 @@ jobs:
with:
files: |
package.json
yarn.lock
packages/twenty-front/**
packages/twenty-ui/**
packages/twenty-shared/**
front-sb-build:
needs: [changed-files-check]
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: depot-ubuntu-24.04-8
env:
REACT_APP_SERVER_BASE_URL: http://localhost:3000
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.11.0
@@ -43,11 +48,6 @@ jobs:
uses: ./.github/workflows/actions/yarn-install
- name: Diagnostic disk space issue
run: df -h
- name: Restore storybook build cache
id: restore-storybook-build-cache
uses: ./.github/workflows/actions/restore-cache
with:
key: ${{ env.STORYBOOK_BUILD_CACHE_KEY }}
- name: Front / Write .env
run: npx nx reset:env twenty-front
- name: Front / Build storybook
@@ -55,7 +55,7 @@ jobs:
- name: Save storybook build cache
uses: ./.github/workflows/actions/save-cache
with:
key: ${{ steps.restore-storybook-build-cache.outputs.cache-primary-key }}
key: ${{ env.STORYBOOK_BUILD_CACHE_KEY_FOR_SAVE_ACTION }}
front-sb-test:
timeout-minutes: 30
runs-on: depot-ubuntu-24.04-8
@@ -68,7 +68,6 @@ jobs:
env:
SHARD_COUNTER: 4
REACT_APP_SERVER_BASE_URL: http://localhost:3000
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
steps:
- name: Fetch local actions
uses: actions/checkout@v4
@@ -81,7 +80,7 @@ jobs:
- name: Restore storybook build cache
uses: ./.github/workflows/actions/restore-cache
with:
key: ${{ env.STORYBOOK_BUILD_CACHE_KEY }}
key: ${{ env.STORYBOOK_BUILD_CACHE_KEY_FOR_RESTORE_ACTION }}
- name: Front / Write .env
run: npx nx reset:env twenty-front
- name: Run storybook tests
@@ -96,7 +95,7 @@ jobs:
path: packages/twenty-front/coverage/storybook/coverage-shard-${{matrix.shard}}.json
merge-reports-and-check-coverage:
timeout-minutes: 30
runs-on: depot-ubuntu-24.04-8
runs-on: ubuntu-latest
needs: front-sb-test
env:
PATH_TO_COVERAGE: packages/twenty-front/coverage/storybook
@@ -128,7 +127,6 @@ jobs:
env:
REACT_APP_SERVER_BASE_URL: http://127.0.0.1:3000
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
steps:
- uses: actions/checkout@v4
with:
@@ -143,16 +141,16 @@ jobs:
run: |
cd packages/twenty-front
touch .env
echo "REACT_APP_SERVER_BASE_URL: $REACT_APP_SERVER_BASE_URL" >> .env
echo "" >> .env
echo "REACT_APP_SERVER_BASE_URL=$REACT_APP_SERVER_BASE_URL" >> .env
- name: Publish to Chromatic
run: npx nx run twenty-front:chromatic:ci
front-task:
needs: changed-files-check
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: depot-ubuntu-24.04-8
runs-on: ubuntu-latest
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
TASK_CACHE_KEY: front-task-${{ matrix.task }}
strategy:
matrix:
@@ -189,8 +187,8 @@ jobs:
key: ${{ steps.restore-task-cache.outputs.cache-primary-key }}
ci-front-status-check:
if: always() && !cancelled()
timeout-minutes: 1
runs-on: depot-ubuntu-24.04-8
timeout-minutes: 5
runs-on: ubuntu-latest
needs:
[
changed-files-check,
+25 -11
View File
@@ -1,4 +1,9 @@
name: "Release: create"
permissions:
contents: read
pull-requests: write
on:
workflow_dispatch:
inputs:
@@ -13,33 +18,42 @@ on:
default: true
description: Create a release after merging the PR
defaults:
run:
shell: bash --noprofile --norc -euo pipefail {0}
jobs:
create_pr:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref }}
- name: Sanitize version
id: sanitize
env:
RAW_VERSION: ${{ github.event.inputs.version }}
run: |
echo version=$(echo ${{ github.event.inputs.version }} | sed 's/^v//') >> $GITHUB_OUTPUT
VERSION="${RAW_VERSION#v}"
printf 'version=%s\n' "$VERSION" >> "$GITHUB_OUTPUT"
- name: Update versions
env:
VERSION: ${{ steps.sanitize.outputs.version }}
run: |
echo ${{ steps.sanitize.outputs.version }} > version.txt
printf '%s\n' "$VERSION" > version.txt
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
branch: release/${{ steps.sanitize.outputs.version }}
commit-message: "chore: release v${{ steps.sanitize.outputs.version }}"
committer: Github Action Deploy <github-action-deploy@twenty.com>
author: Github Action Deploy <github-action-deploy@twenty.com>
title: Release v${{ steps.sanitize.outputs.version }}
labels: |
release
${{ github.event.inputs.create_release == true && 'create_release' || '' }}
branch: release/${{ steps.sanitize.outputs.version }}
commit-message: "chore: release v${{ steps.sanitize.outputs.version }}"
committer: Github Action Deploy <github-action-deploy@twenty.com>
author: Github Action Deploy <github-action-deploy@twenty.com>
title: Release v${{ steps.sanitize.outputs.version }}
labels: |
release
${{ github.event.inputs.create_release == true && 'create_release' || '' }}
+22 -7
View File
@@ -1,9 +1,17 @@
name: "Release: on merge"
permissions:
contents: write
on:
pull_request:
types:
- closed
defaults:
run:
shell: bash --noprofile --norc -euo pipefail {0}
jobs:
tag_and_release:
timeout-minutes: 10
@@ -12,33 +20,40 @@ jobs:
steps:
- name: Check PR Author
id: check_author
env:
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
run: |
if [[ "${{ github.event.pull_request.user.login }}" != "github-actions[bot]" ]]; then
echo "PR author (${AUTHOR}) is not trusted. Exiting."
set -euo pipefail
if [[ "$PR_AUTHOR" != "github-actions[bot]" ]]; then
echo "PR author ($PR_AUTHOR) is not trusted. Exiting."
exit 1
fi
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
ref: main
- name: Get version from PR title
id: extract_version
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
VERSION=$(echo "${{ github.event.pull_request.title }}" | sed -n 's/.*Release v\([0-9.]*\).*/\1/p')
set -euo pipefail
VERSION=$(printf '%s' "$PR_TITLE" | sed -n 's/.*Release v\([0-9][0-9.]*\).*/\1/p')
if [ -z "$VERSION" ]; then
echo "No valid version found in PR title. Exiting."
exit 1
fi
echo "VERSION=$VERSION" >> $GITHUB_ENV
printf 'VERSION=%s\n' "$VERSION" >> "$GITHUB_ENV"
- name: Push new tag
run: |
set -euo pipefail
git config --global user.name 'Github Action Deploy'
git config --global user.email 'github-action-deploy@twenty.com'
git tag v${{ env.VERSION }}
git push origin v${{ env.VERSION }}
git tag "v${{ env.VERSION }}"
git push origin "v${{ env.VERSION }}"
- uses: release-drafter/release-drafter@v5
if: contains(github.event.pull_request.labels.*.name, 'create_release')
+68 -29
View File
@@ -1,4 +1,5 @@
name: CI Server
on:
push:
branches:
@@ -6,9 +7,12 @@ on:
pull_request:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
env:
SERVER_SETUP_CACHE_KEY: server-setup
@@ -19,7 +23,10 @@ jobs:
with:
files: |
package.json
yarn.lock
packages/twenty-server/**
packages/twenty-front/src/generated/**
packages/twenty-front/src/generated-metadata/**
packages/twenty-emails/**
packages/twenty-shared/**
server-setup:
@@ -27,8 +34,6 @@ jobs:
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: depot-ubuntu-24.04-8
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
services:
postgres:
image: twentycrm/twenty-postgres-spilo
@@ -67,10 +72,10 @@ jobs:
with:
tag: scope:backend
tasks: lint,typecheck
- name: Server / Build
run: npx nx build twenty-server
- name: Server / Write .env
run: npx nx reset:env twenty-server
- name: Server / Build
run: npx nx build twenty-server
- name: Server / Create DB
run: |
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "default";'
@@ -87,47 +92,61 @@ jobs:
# If worker failed for other reasons, fail the build
exit $exit_code
fi
- name: Server / Start
run: npx nx start:ci twenty-server &
- name: Waiting for server starting...
run: |
for i in {1..10}; do
if curl -f http://localhost:3000/healthz; then
echo "Server ready!"
exit 0
fi
echo "Waiting..."
sleep 2
done
echo "Server did not become healthy in time" >&2
exit 1
- name: Server / Check for Pending Migrations
run: |
METADATA_MIGRATION_OUTPUT=$(npx nx run twenty-server:typeorm migration:generate metadata-migration-check -d src/database/typeorm/metadata/metadata.datasource.ts || true)
CORE_MIGRATION_OUTPUT=$(npx nx run twenty-server:typeorm migration:generate core-migration-check -d src/database/typeorm/core/core.datasource.ts || true)
METADATA_MIGRATION_FILE=$(ls packages/twenty-server/*metadata-migration-check.ts 2>/dev/null || echo "")
CORE_MIGRATION_FILE=$(ls packages/twenty-server/*core-migration-check.ts 2>/dev/null || echo "")
if [ -n "$METADATA_MIGRATION_FILE" ] || [ -n "$CORE_MIGRATION_FILE" ]; then
if [ -n "$CORE_MIGRATION_FILE" ]; then
echo "::error::Unexpected migration files were generated. Please create a proper migration manually."
echo "$METADATA_MIGRATION_OUTPUT"
echo "$CORE_MIGRATION_OUTPUT"
rm -f packages/twenty-server/*metadata-migration-check.ts packages/twenty-server/*core-migration-check.ts
rm -f packages/twenty-server/*core-migration-check.ts
exit 1
fi
- name: GraphQL / Check for Pending Generation
if: steps.changed-files.outputs.any_changed == 'true'
run: |
# Run GraphQL generation commands
npx nx run twenty-front:graphql:generate
npx nx run twenty-front:graphql:generate --configuration=metadata
# Check if any files were modified
if ! git diff --quiet; then
# Check if GraphQL generated files were modified
if ! git diff --quiet -- packages/twenty-front/src/generated packages/twenty-front/src/generated-metadata; then
echo "::error::GraphQL schema changes detected. Please run 'npx nx run twenty-front:graphql:generate' and 'npx nx run twenty-front:graphql:generate --configuration=metadata' and commit the changes."
echo ""
echo "The following GraphQL schema changes were detected:"
echo "==================================================="
git diff -- packages/twenty-front/src/generated packages/twenty-front/src/generated-metadata
echo "==================================================="
echo ""
echo "Please run 'npx nx run twenty-front:graphql:generate' and 'npx nx run twenty-front:graphql:generate --configuration=metadata' and commit the changes."
echo ""
exit 1
fi
- name: Save server setup
uses: ./.github/workflows/actions/save-cache
with:
key: ${{ steps.restore-server-setup-cache.outputs.cache-primary-key }}
server-test:
timeout-minutes: 30
runs-on: depot-ubuntu-24.04-8
needs: server-setup
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
steps:
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
@@ -149,6 +168,10 @@ jobs:
timeout-minutes: 30
runs-on: depot-ubuntu-24.04-8
needs: server-setup
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4, 5]
services:
postgres:
image: twentycrm/twenty-postgres-spilo
@@ -168,9 +191,25 @@ jobs:
image: redis
ports:
- 6379:6379
clickhouse:
image: clickhouse/clickhouse-server:25.8.8
env:
CLICKHOUSE_PASSWORD: clickhousePassword
CLICKHOUSE_URL: "http://default:clickhousePassword@localhost:8123/twenty"
ports:
- 8123:8123
- 9000:9000
options: >-
--health-cmd "clickhouse-client --host=localhost --port=9000 --user=default --password=clickhousePassword --query='SELECT 1'"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
NODE_ENV: test
ANALYTICS_ENABLED: true
CLICKHOUSE_URL: "http://default:clickhousePassword@localhost:8123/twenty"
CLICKHOUSE_PASSWORD: clickhousePassword
SHARD_COUNTER: 5
steps:
- name: Fetch custom Github Actions and base branch history
uses: actions/checkout@v4
@@ -178,8 +217,9 @@ jobs:
fetch-depth: 0
- name: Install dependencies
uses: ./.github/workflows/actions/yarn-install
- name: Update .env.test for billing
- name: Update .env.test for integrations tests
run: |
echo "" >> .env.test
echo "IS_BILLING_ENABLED=true" >> .env.test
echo "BILLING_STRIPE_API_KEY=test-api-key" >> .env.test
echo "BILLING_STRIPE_BASE_PLAN_PRODUCT_ID=test-base-plan-product-id" >> .env.test
@@ -198,24 +238,23 @@ jobs:
- name: Server / Create Test DB
run: |
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "test";'
- name: Run ClickHouse migrations
run: npx nx clickhouse:migrate twenty-server
- name: Run ClickHouse seeds
run: npx nx clickhouse:seed twenty-server
- name: Server / Run Integration Tests
uses: ./.github/workflows/actions/nx-affected
with:
tag: scope:backend
tasks: 'test:integration'
configuration: 'with-db-reset'
- name: Server / Upload reset-logs file
if: always()
uses: actions/upload-artifact@v4
with:
name: reset-logs
path: reset-logs.log
args: --shard=${{ matrix.shard }}/${{ env.SHARD_COUNTER }}
ci-server-status-check:
if: always() && !cancelled()
timeout-minutes: 1
runs-on: depot-ubuntu-24.04-8
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, server-setup, server-test, server-integration-test]
steps:
- name: Fail job if any needs failed
- name: Fail job if any needs failed
if: contains(needs.*.result, 'failure')
run: exit 1
+6 -4
View File
@@ -1,4 +1,5 @@
name: CI Shared
on:
push:
branches:
@@ -6,9 +7,12 @@ on:
pull_request:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
changed-files-check:
@@ -21,8 +25,6 @@ jobs:
if: needs.changed-files-check.outputs.any_changed == 'true'
timeout-minutes: 30
runs-on: ubuntu-latest
env:
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
strategy:
matrix:
task: [lint, typecheck, test]
@@ -44,7 +46,7 @@ jobs:
tasks: ${{ matrix.task }}
ci-shared-status-check:
if: always() && !cancelled()
timeout-minutes: 1
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, shared-test]
steps:
@@ -4,7 +4,7 @@ on:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
changed-files-check:
@@ -33,6 +33,7 @@ jobs:
echo "Setting up .env file..."
cp .env.example .env
echo "Generating secrets..."
echo "" >> .env
echo "# === Randomly generated secrets ===" >>.env
echo "APP_SECRET=$(openssl rand -base64 32)" >>.env
echo "PGPASSWORD_SUPERUSER=$(openssl rand -hex 16)" >>.env
@@ -84,7 +85,7 @@ jobs:
working-directory: ./packages/twenty-docker/
ci-test-docker-compose-status-check:
if: always() && !cancelled()
timeout-minutes: 1
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, test]
steps:
+4 -1
View File
@@ -1,4 +1,5 @@
name: CI Utils
on:
# it's usually not recommended to use pull_request_target
# but we consider it's safe here if we keep the same steps
@@ -6,6 +7,7 @@ on:
# and: https://github.com/facebook/react-native/pull/34370/files
pull_request_target:
types: [opened, synchronize, reopened, closed]
permissions:
actions: write
checks: write
@@ -13,6 +15,7 @@ permissions:
issues: write
pull-requests: write
statuses: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
# We don't cancel in-progress because this workflow is triggered on
@@ -21,7 +24,7 @@ concurrency:
jobs:
danger-js:
timeout-minutes: 3
timeout-minutes: 5
runs-on: ubuntu-latest
if: github.event.action != 'closed'
steps:
+6 -2
View File
@@ -1,4 +1,8 @@
name: CI Website
permissions:
contents: read
on:
push:
branches:
@@ -8,7 +12,7 @@ on:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
changed-files-check:
@@ -62,7 +66,7 @@ jobs:
NEXT_PUBLIC_KEYSTATIC_GITHUB_APP_SLUG: xxx
ci-website-status-check:
if: always() && !cancelled()
timeout-minutes: 10
timeout-minutes: 5
runs-on: ubuntu-latest
needs: [changed-files-check, website-build]
steps:
+155
View File
@@ -0,0 +1,155 @@
name: 'Pull docs translations from Crowdin'
permissions:
contents: write
pull-requests: write
on:
schedule:
- cron: '0 */2 * * *' # Every two hours
workflow_dispatch:
inputs:
force_pull:
description: 'Force pull translations regardless of status'
required: false
type: boolean
default: false
workflow_call:
inputs:
force_pull:
description: 'Force pull translations regardless of status'
required: false
type: boolean
default: false
pull_request:
paths:
- 'packages/twenty-docs/**'
- 'crowdin.yml'
- '.github/workflows/docs-i18n-pull.yaml'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
pull_docs_translations:
name: Pull docs translations
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
token: ${{ github.token }}
ref: ${{ github.event_name == 'pull_request' && github.head_ref || github.ref }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Setup i18n branch
if: github.event_name != 'pull_request'
run: |
git fetch origin i18n || true
git checkout -B i18n origin/i18n || git checkout -b i18n
- name: Configure git
run: |
git config --global user.name 'github-actions'
git config --global user.email 'github-actions@twenty.com'
- name: Stash any changes before pulling translations
if: github.event_name != 'pull_request'
run: |
git add .
git stash || true
- name: Pull translated docs from Crowdin
if: github.event_name != 'pull_request' && (inputs.force_pull == true || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
uses: crowdin/github-action@v2
with:
upload_sources: false
upload_translations: false
download_translations: true
source: 'packages/twenty-docs/**/*.mdx'
translation: 'packages/twenty-docs/l/%two_letters_code%/**/%original_file_name%'
export_only_approved: false
localization_branch_name: i18n
base_url: 'https://twenty.api.crowdin.com'
skip_untranslated_files: true
push_translations: false
create_pull_request: false
skip_ref_checkout: true
dryrun_action: false
env:
GITHUB_TOKEN: ${{ github.token }}
CROWDIN_PROJECT_ID: '1'
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
- name: Fix file permissions
if: github.event_name != 'pull_request'
run: sudo chown -R runner:docker . || true
- name: Fix translated documentation links
run: bash packages/twenty-docs/scripts/fix-translated-links.sh
- name: Regenerate navigation template
if: github.event_name == 'pull_request'
run: yarn docs:generate-navigation-template
- name: Regenerate docs.json
run: yarn docs:generate
- name: Commit artifacts to pull request branch
if: github.event_name == 'pull_request'
run: |
git add packages/twenty-docs/docs.json packages/twenty-docs/navigation/navigation.template.json
if git diff --staged --quiet --exit-code; then
echo "No navigation/doc changes to commit."
exit 0
fi
git commit -m "chore: sync docs artifacts"
git push origin HEAD:${{ github.head_ref }}
- name: Check for changes and commit
if: github.event_name != 'pull_request'
id: check_changes
run: |
git add .
if ! git diff --staged --quiet --exit-code; then
git commit -m "chore: update docs translations from Crowdin and fix internal links"
echo "changes_detected=true" >> $GITHUB_OUTPUT
else
echo "changes_detected=false" >> $GITHUB_OUTPUT
fi
- name: Push changes
if: github.event_name != 'pull_request' && steps.check_changes.outputs.changes_detected == 'true'
run: git push origin HEAD:i18n
- name: Create pull request
if: github.event_name != 'pull_request' && steps.check_changes.outputs.changes_detected == 'true'
run: |
if git diff --name-only origin/main..HEAD | grep -q .; then
gh pr create -B main -H i18n --title 'i18n - docs translations' --body 'Created by Github action' || true
else
echo "No file differences between branches, skipping PR creation"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+68
View File
@@ -0,0 +1,68 @@
name: 'Push docs to Crowdin'
permissions:
contents: write
on:
workflow_dispatch:
workflow_call:
push:
branches: ['main', 'docs-localized-navigation']
paths:
- 'packages/twenty-docs/**/*.mdx'
- '!packages/twenty-docs/fr/**'
- 'crowdin.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
push_docs:
name: Push documentation to Crowdin
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
token: ${{ github.token }}
ref: ${{ github.ref }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Generate navigation template for Crowdin
run: yarn docs:generate-navigation-template
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Generate navigation template for Crowdin
run: yarn docs:generate-navigation-template
- name: Upload docs to Crowdin
uses: crowdin/github-action@v2
with:
upload_sources: true
upload_translations: false
download_translations: false
localization_branch_name: i18n
base_url: 'https://twenty.api.crowdin.com'
env:
CROWDIN_PROJECT_ID: 1
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
+11 -8
View File
@@ -3,6 +3,10 @@
name: 'Pull translations from Crowdin'
permissions:
contents: write
pull-requests: write
on:
schedule:
- cron: '0 */2 * * *' # Every two hours.
@@ -23,16 +27,12 @@ on:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
pull_translations:
name: Pull translations
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -74,6 +74,8 @@ jobs:
upload_sources: false
upload_translations: false
download_translations: true
source: '**/en.po'
translation: '%original_path%/%locale%.po'
export_only_approved: false
localization_branch_name: i18n
base_url: 'https://twenty.api.crowdin.com'
@@ -91,7 +93,7 @@ jobs:
GITHUB_TOKEN: ${{ github.token }}
CROWDIN_PROJECT_ID: '1'
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
# As the files are extracted from a Docker container, they belong to root:root
# We need to fix this before the next steps
- name: Fix file permissions
@@ -99,10 +101,11 @@ jobs:
- name: Compile translations
id: compile_translations
if: inputs.force_pull || steps.compile_translations_strict.outcome == 'failure'
# Because we have set English as a fallback locale, this condition does not work anymore
# if: inputs.force_pull || steps.compile_translations_strict.outcome == 'failure'
run: |
npx nx run twenty-server:lingui:compile
npx nx run twenty-emails:lingui:compile
npx nx run twenty-emails:lingui:compile
npx nx run twenty-front:lingui:compile
git status
git config --global user.name 'github-actions'
+5 -4
View File
@@ -1,5 +1,9 @@
name: 'Push translations to Crowdin'
permissions:
contents: write
pull-requests: write
on:
workflow_dispatch:
workflow_call:
@@ -8,15 +12,12 @@ on:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
extract_translations:
name: Extract and upload translations
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -0,0 +1,37 @@
name: 'Preview Environment Dispatch'
permissions:
contents: write
actions: write
pull-requests: read
on:
# Using pull_request_target instead of pull_request to have access to secrets for external contributors
# Security note: This is safe because we're only using the repository-dispatch action with limited scope
# and not checking out or running any code from the external contributor's PR
pull_request_target:
types: [opened, synchronize, reopened, labeled]
paths:
- packages/twenty-docker/**
- packages/twenty-server/**
- packages/twenty-front/**
- .github/workflows/preview-env-dispatch.yaml
- .github/workflows/preview-env-keepalive.yaml
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
trigger-preview:
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.action == 'reopened' || (github.event.action == 'labeled' && github.event.label.name == 'preview-app')
timeout-minutes: 5
runs-on: ubuntu-latest
steps:
- name: Trigger preview environment workflow
uses: peter-evans/repository-dispatch@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
event-type: preview-environment
client-payload: '{"pr_number": "${{ github.event.pull_request.number }}", "pr_head_sha": "${{ github.event.pull_request.head.sha }}", "repo_full_name": "${{ github.repository }}"}'
@@ -0,0 +1,159 @@
name: 'Preview Environment Keep Alive'
permissions:
contents: read
pull-requests: write
on:
repository_dispatch:
types: [preview-environment]
jobs:
preview-environment:
timeout-minutes: 310
runs-on: ubuntu-latest
steps:
- name: Checkout PR
uses: actions/checkout@v4
with:
ref: ${{ github.event.client_payload.pr_head_sha }}
- name: Run compose setup
run: |
echo "Patching docker-compose.yml..."
# change image to localbuild using yq
yq eval 'del(.services.server.image)' -i packages/twenty-docker/docker-compose.yml
yq eval '.services.server.build.context = "../../"' -i packages/twenty-docker/docker-compose.yml
yq eval '.services.server.build.dockerfile = "./packages/twenty-docker/twenty/Dockerfile"' -i packages/twenty-docker/docker-compose.yml
yq eval 'del(.services.worker.image)' -i packages/twenty-docker/docker-compose.yml
yq eval '.services.worker.build.context = "../../"' -i packages/twenty-docker/docker-compose.yml
yq eval '.services.worker.build.dockerfile = "./packages/twenty-docker/twenty/Dockerfile"' -i packages/twenty-docker/docker-compose.yml
echo "Adding SIGN_IN_PREFILLED environment variable to server service..."
yq eval '.services.server.environment.SIGN_IN_PREFILLED = "${SIGN_IN_PREFILLED}"' -i packages/twenty-docker/docker-compose.yml
echo "Setting up .env file..."
cp packages/twenty-docker/.env.example packages/twenty-docker/.env
echo "Generating secrets..."
echo "" >> packages/twenty-docker/.env
echo "# === Randomly generated secrets ===" >> packages/twenty-docker/.env
echo "APP_SECRET=$(openssl rand -base64 32)" >> packages/twenty-docker/.env
echo "PG_DATABASE_PASSWORD=$(openssl rand -hex 16)" >> packages/twenty-docker/.env
echo "SIGN_IN_PREFILLED=true" >> packages/twenty-docker/.env
echo "Docker compose build..."
cd packages/twenty-docker/
docker compose build
working-directory: ./
- name: Create Tunnel
id: expose-tunnel
uses: codetalkio/expose-tunnel@v1.5.0
with:
service: bore.pub
port: 3000
- name: Start services with correct SERVER_URL
run: |
cd packages/twenty-docker/
# Update the SERVER_URL with the tunnel URL
echo "Setting SERVER_URL to ${{ steps.expose-tunnel.outputs.tunnel-url }}"
sed -i '/SERVER_URL=/d' .env
echo "" >> .env
echo "SERVER_URL=${{ steps.expose-tunnel.outputs.tunnel-url }}" >> .env
# Start the services
echo "Docker compose up..."
docker compose up -d || {
echo "Docker compose failed to start"
docker compose logs
exit 1
}
echo "Waiting for services to be ready..."
count=0
while [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-db-1) = "healthy" ] || [ ! $(docker inspect --format='{{.State.Health.Status}}' twenty-server-1) = "healthy" ]; do
sleep 5
count=$((count+1))
if [ $count -gt 60 ]; then
echo "Timeout waiting for services to be ready"
docker compose logs
exit 1
fi
echo "Still waiting for services... ($count/60)"
done
echo "All services are up and running!"
working-directory: ./
- name: Seed Dev Workspace
run: |
cd packages/twenty-docker/
echo "Seeding full dev workspace..."
if ! docker compose exec -T server yarn command:prod -- workspace:seed:dev; then
echo "❌ Seeding full dev workspace failed. Dumping server logs..."
docker compose logs server
exit 1
fi
working-directory: ./
- name: Output tunnel URL to logs
run: |
echo "✅ Preview Environment Ready!"
echo "🔗 Preview URL: ${{ steps.expose-tunnel.outputs.tunnel-url }}"
echo "⏱️ This environment will be available for 5 hours"
- name: Post comment on PR
uses: actions/github-script@v6
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const COMMENT_MARKER = '<!-- PR_PREVIEW_ENV -->';
const commentBody = `${COMMENT_MARKER}
🚀 **Preview Environment Ready!**
Your preview environment is available at: ${{ steps.expose-tunnel.outputs.tunnel-url }}
This environment will automatically shut down when the PR is closed or after 5 hours.`;
// Get all comments
const {data: comments} = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ github.event.client_payload.pr_number }},
});
// Find our comment
const botComment = comments.find(comment => comment.body.includes(COMMENT_MARKER));
if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
});
console.log('Updated existing comment');
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ github.event.client_payload.pr_number }},
body: commentBody
});
console.log('Created new comment');
}
- name: Keep tunnel alive for 5 hours
run: timeout 300m sleep 18000 # Stop on whichever we reach first (300m or 5hour sleep)
- name: Cleanup
if: always()
run: |
cd packages/twenty-docker/
docker compose down -v
working-directory: ./
+6 -1
View File
@@ -9,6 +9,7 @@
.nx/installation
.nx/cache
.nx/workspace-data
.pnp.*
.yarn/*
@@ -42,4 +43,8 @@ dump.rdb
/flake.lock
/flake.nix
.crowdin.yml
.crowdin.yml
.react-email/
mcp.json
/.junie/
+24
View File
@@ -0,0 +1,24 @@
{
"mcpServers": {
"postgres": {
"type": "stdio",
"command": "uv",
"args": ["run", "postgres-mcp", "--access-mode=unrestricted"],
"env": {
"DATABASE_URI": "${PG_DATABASE_URL}"
}
},
"playwright": {
"type": "stdio",
"command": "npx",
"args": ["@playwright/mcp@latest", "--no-sandbox", "--headless"],
"env": {}
},
"context7": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"],
"env": {}
}
}
}
+1 -1
View File
@@ -1 +1 @@
18.17.1
24.5.0
+2 -2
View File
@@ -1,5 +1,5 @@
{
"singleQuote": true,
"trailingComma": "all",
"endOfLine": "auto"
}
"endOfLine": "lf"
}
+28 -13
View File
@@ -5,13 +5,10 @@
{
"name": "twenty-server - start debug",
"type": "node",
"runtimeVersion": "24.5",
"request": "launch",
"runtimeExecutable": "npx",
"runtimeArgs": [
"nx",
"run",
"twenty-server:start"
],
"runtimeArgs": ["nx", "run", "twenty-server:start"],
"outputCapture": "std",
"internalConsoleOptions": "openOnSessionStart",
"console": "internalConsole",
@@ -22,11 +19,7 @@
"type": "node",
"request": "launch",
"runtimeExecutable": "npx",
"runtimeArgs": [
"nx",
"run",
"twenty-server:worker"
],
"runtimeArgs": ["nx", "run", "twenty-server:worker"],
"outputCapture": "std",
"internalConsoleOptions": "openOnSessionStart",
"console": "internalConsole",
@@ -37,7 +30,7 @@
"type": "node",
"request": "launch",
"runtimeExecutable": "npx",
"runtimeVersion": "18",
"runtimeVersion": "24.5",
"runtimeArgs": [
"nx",
"run",
@@ -73,6 +66,28 @@
"--",
"--config",
"./jest-integration.config.ts",
"${relativeFile}",
"--silent=false"
],
"cwd": "${workspaceFolder}/packages/twenty-server",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"env": {
"NODE_ENV": "test"
}
},
{
"type": "node",
"request": "launch",
"name": "twenty-server - debug unit test file (to launch with test file open)",
"runtimeExecutable": "npx",
"runtimeArgs": [
"nx",
"run",
"twenty-server:jest",
"--",
"--config",
"./jest.config.mjs",
"${relativeFile}"
],
"cwd": "${workspaceFolder}/packages/twenty-server",
@@ -80,7 +95,7 @@
"internalConsoleOptions": "neverOpen",
"env": {
"NODE_ENV": "test"
},
}
}
]
}
}
+6 -4
View File
@@ -1,6 +1,8 @@
{
"editor.formatOnSave": false,
"files.eol": "auto",
"files.eol": "\n",
"files.insertFinalNewline": true,
"files.trimTrailingWhitespace": true,
"[typescript]": {
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
@@ -43,12 +45,12 @@
],
"typescript.preferences.importModuleSpecifier": "non-relative",
"search.exclude": {
"**/.yarn": true,
"**/.yarn": true
},
"eslint.debug": true,
"files.associations": {
".cursorrules": "markdown"
},
"jestrunner.codeLensSelector": "**/*.{test,spec,integration-spec}.{js,jsx,ts,tsx}"
}
"jestrunner.codeLensSelector": "**/*.{test,spec,integration-spec}.{js,jsx,ts,tsx}",
"typescript.tsdk": "node_modules/typescript/lib"
}
-4
View File
@@ -4,10 +4,6 @@
"name": "ROOT",
"path": "../"
},
{
"name": "packages/twenty-chrome-extension",
"path": "../packages/twenty-chrome-extension"
},
{
"name": "packages/twenty-docker",
"path": "../packages/twenty-docker"
@@ -0,0 +1,45 @@
diff --git a/commonjs/helpers/phoneInputHelpers.js b/commonjs/helpers/phoneInputHelpers.js
index 8fd1b16ec670ab7d0abcb800a2edd7848e86ce1e..ab6e0dd90def507629c2ead59fba929a739f0759 100644
--- a/commonjs/helpers/phoneInputHelpers.js
+++ b/commonjs/helpers/phoneInputHelpers.js
@@ -574,7 +574,9 @@ function onPhoneDigitsChange(phoneDigits, _ref5) {
// Generate the new `value` property.
var value;
if (phoneDigits) {
- if (phoneDigits[0] === '+') {
+ if(phoneDigits === prevPhoneDigits) {
+ value = e164(phoneDigits, country, metadata)
+ } else if (phoneDigits[0] === '+') {
if (phoneDigits === '+') {
value = undefined;
} else if (country && (0, _getInternationalPhoneNumberPrefix["default"])(country, metadata).indexOf(phoneDigits) === 0) {
diff --git a/modules/helpers/phoneInputHelpers.js b/modules/helpers/phoneInputHelpers.js
index 75e8463f6b5d32c560d1dec2776671bee2af1d07..99af2904807cc3c23aea566bbeebda2a5bc9afa4 100644
--- a/modules/helpers/phoneInputHelpers.js
+++ b/modules/helpers/phoneInputHelpers.js
@@ -551,7 +551,9 @@ export function onPhoneDigitsChange(phoneDigits, _ref5) {
// Generate the new `value` property.
var value;
if (phoneDigits) {
- if (phoneDigits[0] === '+') {
+ if(phoneDigits === prevPhoneDigits) {
+ value = e164(phoneDigits, country, metadata)
+ } else if (phoneDigits[0] === '+') {
if (phoneDigits === '+') {
value = undefined;
} else if (country && getInternationalPhoneNumberPrefix(country, metadata).indexOf(phoneDigits) === 0) {
diff --git a/react-styleguidist/project/source/helpers/phoneInputHelpers.js b/react-styleguidist/project/source/helpers/phoneInputHelpers.js
index b844ef0fd183fe4f45e436bdb2382fc2987dcef2..8960834900e59a57e130521fd369e82fe05f5090 100644
--- a/react-styleguidist/project/source/helpers/phoneInputHelpers.js
+++ b/react-styleguidist/project/source/helpers/phoneInputHelpers.js
@@ -505,7 +505,9 @@ export function onPhoneDigitsChange(phoneDigits, {
// Generate the new `value` property.
let value
if (phoneDigits) {
- if (phoneDigits[0] === '+') {
+ if(phoneDigits === prevPhoneDigits) {
+ value = e164(phoneDigits, country, metadata)
+ } else if (phoneDigits[0] === '+') {
if (phoneDigits === '+') {
value = undefined
} else if (country && getInternationalPhoneNumberPrefix(country, metadata).indexOf(phoneDigits) !== 0) {
-925
View File
File diff suppressed because one or more lines are too long
+942
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -6,4 +6,4 @@ enableInlineHunks: true
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-4.4.0.cjs
yarnPath: .yarn/releases/yarn-4.9.2.cjs
+152
View File
@@ -0,0 +1,152 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Twenty is an open-source CRM built with modern technologies in a monorepo structure. The codebase is organized as an Nx workspace with multiple packages.
## Key Commands
### Development
```bash
# Start development environment (frontend + backend + worker)
yarn start
# Individual package development
npx nx start twenty-front # Start frontend dev server
npx nx start twenty-server # Start backend server
npx nx run twenty-server:worker # Start background worker
```
### Testing
```bash
# Run tests
npx nx test twenty-front # Frontend unit tests
npx nx test twenty-server # Backend unit tests
npx nx run twenty-server:test:integration:with-db-reset # Integration tests with DB reset
# Storybook
npx nx storybook:build twenty-front # Build Storybook
npx nx storybook:serve-and-test:static twenty-front # Run Storybook tests
When testing the UI end to end, click on "Continue with Email" and use the prefilled credentials.
```
### Code Quality
```bash
# Linting
npx nx lint twenty-front # Frontend linting
npx nx lint twenty-server # Backend linting
npx nx lint twenty-front --fix # Auto-fix linting issues
# Type checking
npx nx typecheck twenty-front
npx nx typecheck twenty-server
# Format code
npx nx fmt twenty-front
npx nx fmt twenty-server
```
### Build
```bash
# Build packages
npx nx build twenty-front
npx nx build twenty-server
```
### Database Operations
```bash
# Database management
npx nx database:reset twenty-server # Reset database
npx nx run twenty-server:database:init:prod # Initialize database
npx nx run twenty-server:database:migrate:prod # Run migrations
# Generate migration
npx nx run twenty-server:typeorm migration:generate src/database/typeorm/core/migrations/common/[name] -d src/database/typeorm/core/core.datasource.ts
# Sync metadata
npx nx run twenty-server:command workspace:sync-metadata
```
### GraphQL
```bash
# Generate GraphQL types
npx nx run twenty-front:graphql:generate
```
## Architecture Overview
### Tech Stack
- **Frontend**: React 18, TypeScript, Recoil (state management), Emotion (styling), Vite
- **Backend**: NestJS, TypeORM, PostgreSQL, Redis, GraphQL (with GraphQL Yoga)
- **Monorepo**: Nx workspace managed with Yarn 4
### Package Structure
```
packages/
├── twenty-front/ # React frontend application
├── twenty-server/ # NestJS backend API
├── twenty-ui/ # Shared UI components library
├── twenty-shared/ # Common types and utilities
├── twenty-emails/ # Email templates with React Email
├── twenty-website/ # Next.js documentation website
├── twenty-zapier/ # Zapier integration
└── twenty-e2e-testing/ # Playwright E2E tests
```
### Key Development Principles
- **Functional components only** (no class components)
- **Named exports only** (no default exports)
- **Types over interfaces** (except when extending third-party interfaces)
- **String literals over enums** (except for GraphQL enums)
- **No 'any' type allowed**
- **Event handlers preferred over useEffect** for state updates
### State Management
- **Recoil** for global state management
- Component-specific state with React hooks
- GraphQL cache managed by Apollo Client
### Backend Architecture
- **NestJS modules** for feature organization
- **TypeORM** for database ORM with PostgreSQL
- **GraphQL** API with code-first approach
- **Redis** for caching and session management
- **BullMQ** for background job processing
### Database
- **PostgreSQL** as primary database
- **Redis** for caching and sessions
- **TypeORM migrations** for schema management
- **ClickHouse** for analytics (when enabled)
## Development Workflow
IMPORTANT: Use Context7 for code generation, setup or configuration steps, or library/API documentation. Automatically use the Context7 MCP tools to resolve library IDs and get library docs without waiting for explicit requests.
### Before Making Changes
1. Always run linting and type checking after code changes
2. Test changes with relevant test suites
3. Ensure database migrations are properly structured
4. Check that GraphQL schema changes are backward compatible
### Code Style Notes
- Use **Emotion** for styling with styled-components pattern
- Follow **Nx** workspace conventions for imports
- Use **Lingui** for internationalization
- Components should be in their own directories with tests and stories
### Testing Strategy
- **Unit tests** with Jest for both frontend and backend
- **Integration tests** for critical backend workflows
- **Storybook** for component development and testing
- **E2E tests** with Playwright for critical user flows
## Important Files
- `nx.json` - Nx workspace configuration with task definitions
- `tsconfig.base.json` - Base TypeScript configuration
- `package.json` - Root package with workspace definitions
- `.cursor/rules/` - Development guidelines and best practices
+36 -8
View File
@@ -1,12 +1,17 @@
postgres-on-docker:
docker run -d \
DOCKER_NETWORK=twenty_network
ensure-docker-network:
docker network inspect $(DOCKER_NETWORK) >/dev/null 2>&1 || docker network create $(DOCKER_NETWORK)
postgres-on-docker: ensure-docker-network
docker run -d --network $(DOCKER_NETWORK) \
--name twenty_pg \
-e PGUSER_SUPERUSER=postgres \
-e PGPASSWORD_SUPERUSER=postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e ALLOW_NOSSL=true \
-v twenty_db_data:/home/postgres/pgdata \
-v twenty_db_data:/var/lib/postgresql/data \
-p 5432:5432 \
twentycrm/twenty-postgres-spilo:latest
postgres:16
@echo "Waiting for PostgreSQL to be ready..."
@until docker exec twenty_pg psql -U postgres -d postgres \
-c 'SELECT pg_is_in_recovery();' 2>/dev/null | grep -q 'f'; do \
@@ -16,5 +21,28 @@ postgres-on-docker:
-c "CREATE DATABASE \"default\" WITH OWNER postgres;" \
-c "CREATE DATABASE \"test\" WITH OWNER postgres;"
redis-on-docker:
docker run -d --name twenty_redis -p 6379:6379 redis/redis-stack-server:latest
redis-on-docker: ensure-docker-network
docker run -d --network $(DOCKER_NETWORK) --name twenty_redis -p 6379:6379 redis/redis-stack-server:latest
clickhouse-on-docker: ensure-docker-network
docker run -d --network $(DOCKER_NETWORK) --name twenty_clickhouse -p 8123:8123 -p 9000:9000 -e CLICKHOUSE_PASSWORD=devPassword clickhouse/clickhouse-server:latest \
grafana-on-docker: ensure-docker-network
docker run -d --network $(DOCKER_NETWORK) \
--name twenty_grafana \
-p 4000:3000 \
-e GF_SECURITY_ADMIN_USER=admin \
-e GF_SECURITY_ADMIN_PASSWORD=admin \
-e GF_INSTALL_PLUGINS=grafana-clickhouse-datasource \
-v $(PWD)/packages/twenty-docker/grafana/provisioning/datasources:/etc/grafana/provisioning/datasources \
grafana/grafana-oss:latest
opentelemetry-collector-on-docker: ensure-docker-network
docker run -d --network $(DOCKER_NETWORK) \
--name twenty_otlp_collector \
-p 4317:4317 \
-p 4318:4318 \
-p 13133:13133 \
-v $(PWD)/packages/twenty-docker/otel-collector/otel-collector-config.yaml:/etc/otel-collector-config.yaml \
otel/opentelemetry-collector-contrib:latest \
--config /etc/otel-collector-config.yaml
+55 -82
View File
@@ -1,34 +1,32 @@
<br>
<p align="center">
<a href="https://www.twenty.com">
<img src="./packages/twenty-website/public/images/core/logo.svg" width="100px" alt="Twenty logo" />
</a>
</p>
<h2 align="center" >The #1 Open-Source CRM </h3>
<h2 align="center" >The #1 Open-Source CRM </h2>
<p align="center"><a href="https://twenty.com">🌐 Website</a> · <a href="https://twenty.com/developers">📚 Documentation</a> · <a href="https://github.com/orgs/twentyhq/projects/1"><img src="./packages/twenty-website/public/images/readme/planner-icon.svg" width="12" height="12"/> Roadmap </a> · <a href="https://discord.gg/cx5n4Jzs57"><img src="./packages/twenty-website/public/images/readme/discord-icon.svg" width="12" height="12"/> Discord</a> · <a href="https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty"><img src="./packages/twenty-website/public/images/readme/figma-icon.png" width="12" height="12"/> Figma</a><p>
<p align="center"><a href="https://twenty.com">🌐 Website</a> · <a href="https://docs.twenty.com">📚 Documentation</a> · <a href="https://github.com/orgs/twentyhq/projects/1"><img src="./packages/twenty-website/public/images/readme/planner-icon.svg" width="12" height="12"/> Roadmap </a> · <a href="https://discord.gg/cx5n4Jzs57"><img src="./packages/twenty-website/public/images/readme/discord-icon.svg" width="12" height="12"/> Discord</a> · <a href="https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty"><img src="./packages/twenty-website/public/images/readme/figma-icon.png" width="12" height="12"/> Figma</a></p>
<br />
<p align="center">
<a href="https://www.twenty.com">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/preview-dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/preview-light.png">
<img src="./packages/twenty-docs/static/img/preview-light.png" alt="Companies view" />
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/github-cover-dark.png" />
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/github-cover-light.png" />
<img src="./packages/twenty-website/public/images/readme/github-cover-light.png" alt="Cover" />
</picture>
</a>
</p>
<br>
<br />
# Installation
# Installation
See:
🚀 [Self-hosting](https://twenty.com/developers/section/self-hosting)
🖥️ [Local Setup](https://twenty.com/developers/local-setup)
See:
🚀 [Self-hosting](https://docs.twenty.com/developers/self-hosting/docker-compose)
🖥️ [Local Setup](https://docs.twenty.com/developers/local-setup)
# Does the world need another CRM?
@@ -40,123 +38,98 @@ We built Twenty for three reasons:
**We believe in Open-source and community.** Hundreds of developers are already building Twenty together. Once we have plugin capabilities, a whole ecosystem will grow around it.
<br>
<br />
# What You Can Do With Twenty
We're currently developing Twenty's beta version.
Please feel free to flag any specific needs you have by creating an issue.
Please feel free to flag any specific needs you have by creating an issue.
Below are a few features we have implemented to date:
+ [Add, filter, sort, edit, and track customers](#add-filter-sort-edit-and-track-customers)
+ [Create one or several opportunities for each company](#create-one-or-several-opportunities-for-each-company)
+ [See rich notes tasks displayed in a timeline](#see-rich-notes-tasks-displayed-in-a-timeline)
+ [Create tasks on records](#create-tasks-on-records)
+ [Navigate quickly through the app using keyboard shortcuts and search](#navigate-quickly-through-the-app-using-keyboard-shortcuts-and-search)
+ [Personalize layouts with filters, sort, group by, kanban and table views](#personalize-layouts-with-filters-sort-group-by-kanban-and-table-views)
+ [Customize your objects and fields](#customize-your-objects-and-fields)
+ [Create and manage permissions with custom roles](#create-and-manage-permissions-with-custom-roles)
+ [Automate workflow with triggers and actions](#automate-workflow-with-triggers-and-actions)
+ [Emails, calendar events, files, and more](#emails-calendar-events-files-and-more)
## Add, filter, sort, edit, and track customers:
## Personalize layouts with filters, sort, group by, kanban and table views
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/index-dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/index-light.png">
<img src="./packages/twenty-docs/static/img/visualise-customer-light.png" alt="Companies view" />
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/views-dark.png" />
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/views-light.png" />
<img src="./packages/twenty-website/public/images/readme/views-light.png" alt="Companies Kanban Views" />
</picture>
</p>
## Create one or several opportunities for each company:
## Customize your objects and fields
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/kanban-dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/kanban-light.png">
<img src="./packages/twenty-docs/static/img/follow-your-deals-light.png" alt="Companies view" />
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/data-model-dark.png" />
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/data-model-light.png" />
<img src="./packages/twenty-website/public/images/readme/data-model-light.png" alt="Setting Custom Objects" />
</picture>
</p>
## Track deals effortlessly with the email integration:
## Create and manage permissions with custom roles
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/emails-dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/emails-light.png">
<img src="./packages/twenty-docs/static/img/rich-notes-light.png" alt="Companies view" />
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/permissions-dark.png" />
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/permissions-light.png" />
<img src="./packages/twenty-website/public/images/readme/permissions-light.png" alt="Permissions" />
</picture>
</p>
## Tailor your data model to meet business needs:
## Automate workflow with triggers and actions
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/data-dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/data-light.png">
<img src="./packages/twenty-docs/static/img/rich-notes-light.png" alt="Companies view" />
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/workflows-dark.png" />
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/workflows-light.png" />
<img src="./packages/twenty-website/public/images/readme/workflows-light.png" alt="Workflows" />
</picture>
</p>
## See rich notes displayed in a timeline:
## Emails, calendar events, files, and more
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/notes-dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/notes-light.png">
<img src="./packages/twenty-docs/static/img/rich-notes-light.png" alt="Companies view" />
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/plus-other-features-dark.png" />
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/refs/heads/main/packages/twenty-website/public/images/readme/plus-other-features-light.png" />
<img src="./packages/twenty-website/public/images/readme/plus-other-features-light.png" alt="Other Features" />
</picture>
</p>
## Create tasks on records
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/tasks-dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/tasks-light.png">
<img src="./packages/twenty-docs/static/img/create-tasks-light.png" alt="Companies view" />
</picture>
</p>
## Navigate quickly through the app using keyboard shortcuts and search:
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/keyboard-dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/keyboard-light.png">
<img src="./packages/twenty-docs/static/img/shortcut-navigation-light.png" alt="Companies view" />
</picture>
</p>
## Connect your CRM to all your tools through our APIs and Webhooks.
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/api-dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/twentyhq/twenty/v0.12.0/packages/twenty-docs/static/img/api-light.png">
<img src="./packages/twenty-docs/static/img/shortcut-navigation-light.png" alt="Companies view" />
</picture>
</p>
<br>
<br />
# Stack
- [TypeScript](https://www.typescriptlang.org/)
- [Nx](https://nx.dev/)
- [NestJS](https://nestjs.com/), with [BullMQ](https://bullmq.io/), [PostgreSQL](https://www.postgresql.org/), [Redis](https://redis.io/)
- [React](https://reactjs.org/), with [Recoil](https://recoiljs.org/) and [Emotion](https://emotion.sh/)
- [Greptile](https://greptile.com) for code reviews.
- [Lingui](https://lingui.dev/) and [Crowdin](https://twenty.crowdin.com/twenty) for translations.
- [React](https://reactjs.org/), with [Recoil](https://recoiljs.org/), [Emotion](https://emotion.sh/) and [Lingui](https://lingui.dev/)
# Thanks
<p align="center">
<a href="https://www.chromatic.com/"><img src="./packages/twenty-website/public/images/readme/chromatic.png" height="30" alt="Chromatic" /></a>
<a href="https://greptile.com"><img src="./packages/twenty-website/public/images/readme/greptile.png" height="30" alt="Greptile" /></a>
<a href="https://sentry.io/"><img src="./packages/twenty-website/public/images/readme/sentry.png" height="30" alt="Sentry" /></a>
<a href="https://crowdin.com/"><img src="./packages/twenty-website/public/images/readme/crowdin.png" height="30" alt="Crowdin" /></a>
</p>
Thanks to these amazing services that we use and recommend for UI testing (Chromatic), code review (Greptile), catching bugs (Sentry) and translating (Crowdin).
# Join the Community
- Star the repo
- Subscribe to releases (watch -> custom -> releases)
- Follow us on [Twitter](https://twitter.com/twentycrm) or [LinkedIn](https://www.linkedin.com/company/twenty/)
- Follow us on [Twitter](https://twitter.com/twentycrm) or [LinkedIn](https://www.linkedin.com/company/twenty/)
- Join our [Discord](https://discord.gg/cx5n4Jzs57)
- Improve translations on [Crowdin](https://twenty.crowdin.com/twenty)
- [Contributions](https://github.com/twentyhq/twenty/contribute) are, of course, most welcome!
- Improve translations on [Crowdin](https://twenty.crowdin.com/twenty)
- [Contributions](https://github.com/twentyhq/twenty/contribute) are, of course, most welcome!
+33 -1
View File
@@ -27,5 +27,37 @@ files: [
# e.g. "/resources/%two_letters_code%/%original_file_name%"
#
"translation": "%original_path%/%locale%.po",
},
{
#
# MDX documentation files - user-guide
# Using md type to preserve JSX component structure
# This prevents Crowdin from reformatting <Warning>, <Accordion>, etc.
#
"source": "packages/twenty-docs/user-guide/**/*.mdx",
"translation": "packages/twenty-docs/l/%two_letters_code%/user-guide/**/%original_file_name%",
},
{
#
# MDX documentation files - developers
# Using md type to preserve JSX component structure
#
"source": "packages/twenty-docs/developers/**/*.mdx",
"translation": "packages/twenty-docs/l/%two_letters_code%/developers/**/%original_file_name%",
},
{
#
# MDX documentation files - twenty-ui
# Using md type to preserve JSX component structure
#
"source": "packages/twenty-docs/twenty-ui/**/*.mdx",
"translation": "packages/twenty-docs/l/%two_letters_code%/twenty-ui/**/%original_file_name%",
},
{
#
# Navigation labels template - translated into per-locale navigation.json
#
"source": "packages/twenty-docs/navigation/navigation.template.json",
"translation": "packages/twenty-docs/l/%two_letters_code%/navigation.json",
}
]
]
+217
View File
@@ -0,0 +1,217 @@
import js from '@eslint/js';
import nxPlugin from '@nx/eslint-plugin';
import typescriptEslint from '@typescript-eslint/eslint-plugin';
import typescriptParser from '@typescript-eslint/parser';
import importPlugin from 'eslint-plugin-import';
import linguiPlugin from 'eslint-plugin-lingui';
import * as mdxPlugin from 'eslint-plugin-mdx';
import preferArrowPlugin from 'eslint-plugin-prefer-arrow';
import prettierPlugin from 'eslint-plugin-prettier';
import unicornPlugin from 'eslint-plugin-unicorn';
import unusedImportsPlugin from 'eslint-plugin-unused-imports';
import jsoncParser from 'jsonc-eslint-parser';
export default [
// Base JavaScript configuration
js.configs.recommended,
// Lingui recommended rules
linguiPlugin.configs['flat/recommended'],
// Global ignores
{
ignores: ['**/node_modules/**'],
},
// Base configuration for all files
{
files: ['**/*.{js,jsx,ts,tsx}'],
plugins: {
prettier: prettierPlugin,
lingui: linguiPlugin,
'@nx': nxPlugin,
'prefer-arrow': preferArrowPlugin,
import: importPlugin,
'unused-imports': unusedImportsPlugin,
unicorn: unicornPlugin,
},
rules: {
// General rules
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'no-console': [
'warn',
{ allow: ['group', 'groupCollapsed', 'groupEnd'] },
],
'no-control-regex': 0,
'no-debugger': 'error',
'no-duplicate-imports': 'error',
'no-undef': 'off',
'no-unused-vars': 'off',
// Nx rules
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: [],
depConstraints: [
{
sourceTag: 'scope:apps',
onlyDependOnLibsWithTags: ['scope:apps', 'scope:sdk'],
},
{
sourceTag: 'scope:sdk',
onlyDependOnLibsWithTags: ['scope:sdk', 'scope:shared'],
},
{
sourceTag: 'scope:shared',
onlyDependOnLibsWithTags: ['scope:shared'],
},
{
sourceTag: 'scope:backend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:backend'],
},
{
sourceTag: 'scope:frontend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:frontend'],
},
{
sourceTag: 'scope:zapier',
onlyDependOnLibsWithTags: ['scope:shared'],
},
],
},
],
// Import rules
'import/no-relative-packages': 'error',
'import/no-useless-path-segments': 'error',
'import/no-duplicates': ['error', { considerQueryString: true }],
// Prefer arrow functions
'prefer-arrow/prefer-arrow-functions': [
'error',
{
disallowPrototype: true,
singleReturnOnly: false,
classPropertiesAllowed: false,
},
],
// Unused imports
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
},
},
// TypeScript specific configuration
{
files: ['**/*.{ts,tsx}'],
languageOptions: {
parser: typescriptParser,
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
plugins: {
'@typescript-eslint': typescriptEslint,
},
rules: {
// TypeScript rules
'no-redeclare': 'off', // Turn off base rule for TypeScript
'@typescript-eslint/no-redeclare': 'error', // Use TypeScript-aware version
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
fixStyle: 'inline-type-imports',
},
],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/no-empty-interface': [
'error',
{
allowSingleExtends: true,
},
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-unused-vars': 'off',
},
},
// JavaScript specific configuration
{
files: ['*.{js,jsx}'],
rules: {
// JavaScript-specific rules if needed
},
},
// Test files
{
files: [
'*.spec.@(ts|tsx|js|jsx)',
'*.integration-spec.@(ts|tsx|js|jsx)',
'*.test.@(ts|tsx|js|jsx)',
],
languageOptions: {
globals: {
jest: true,
describe: true,
it: true,
expect: true,
beforeEach: true,
afterEach: true,
beforeAll: true,
afterAll: true,
},
},
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
// JSON files
{
files: ['**/*.json'],
languageOptions: {
parser: jsoncParser,
},
},
// MDX files
{
...mdxPlugin.flat,
plugins: {
...mdxPlugin.flat.plugins,
'@nx': nxPlugin,
},
},
mdxPlugin.flatCodeBlocks,
{
files: ['**/*.mdx'],
rules: {
'no-unused-vars': 'off',
'unused-imports/no-unused-imports': 'off',
'unused-imports/no-unused-vars': 'off',
// Enforce JSX tags on separate lines to prevent Crowdin translation issues
'@nx/workspace-mdx-component-newlines': 'error',
// Disallow angle bracket placeholders to prevent Crowdin translation errors
'@nx/workspace-no-angle-bracket-placeholders': 'error',
},
},
];
+302
View File
@@ -0,0 +1,302 @@
import js from '@eslint/js';
import nxPlugin from '@nx/eslint-plugin';
import typescriptEslint from '@typescript-eslint/eslint-plugin';
import typescriptParser from '@typescript-eslint/parser';
import importPlugin from 'eslint-plugin-import';
import linguiPlugin from 'eslint-plugin-lingui';
import preferArrowPlugin from 'eslint-plugin-prefer-arrow';
import prettierPlugin from 'eslint-plugin-prettier';
import reactPlugin from 'eslint-plugin-react';
import reactHooksPlugin from 'eslint-plugin-react-hooks';
import reactRefreshPlugin from 'eslint-plugin-react-refresh';
import unicornPlugin from 'eslint-plugin-unicorn';
import unusedImportsPlugin from 'eslint-plugin-unused-imports';
import jsoncParser from 'jsonc-eslint-parser';
export default [
// Base JavaScript configuration
js.configs.recommended,
// Lingui recommended rules
linguiPlugin.configs['flat/recommended'],
// Base configuration for all files
{
files: ['**/*.{js,jsx,ts,tsx}'],
plugins: {
'react': reactPlugin,
'react-hooks': reactHooksPlugin,
'react-refresh': reactRefreshPlugin,
'prettier': prettierPlugin,
'lingui': linguiPlugin,
'@nx': nxPlugin,
'prefer-arrow': preferArrowPlugin,
'import': importPlugin,
'unused-imports': unusedImportsPlugin,
'unicorn': unicornPlugin,
},
settings: {
react: {
version: 'detect',
},
},
rules: {
// General rules
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
'no-console': ['warn', { allow: ['group', 'groupCollapsed', 'groupEnd'] }],
'no-control-regex': 0,
'no-debugger': 'error',
'no-duplicate-imports': 'error',
'no-undef': 'off',
'no-unused-vars': 'off',
'prettier/prettier': 'error',
// Nx rules
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: [],
depConstraints: [
{
sourceTag: 'scope:shared',
onlyDependOnLibsWithTags: ['scope:shared'],
},
{
sourceTag: 'scope:backend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:backend'],
},
{
sourceTag: 'scope:frontend',
onlyDependOnLibsWithTags: ['scope:shared', 'scope:frontend'],
},
{
sourceTag: 'scope:zapier',
onlyDependOnLibsWithTags: ['scope:shared'],
},
],
},
],
// Import rules
'import/no-relative-packages': 'error',
'import/no-useless-path-segments': 'error',
'import/no-duplicates': ['error', { considerQueryString: true }],
// Prefer arrow functions
'prefer-arrow/prefer-arrow-functions': [
'error',
{
disallowPrototype: true,
singleReturnOnly: false,
classPropertiesAllowed: false,
},
],
// Unused imports
'unused-imports/no-unused-imports': 'warn',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
// React rules
'react/no-unescaped-entities': 'off',
'react/prop-types': 'off',
'react/jsx-key': 'off',
'react/display-name': 'off',
'react/jsx-uses-react': 'off',
'react/react-in-jsx-scope': 'off',
'react/jsx-no-useless-fragment': 'off',
'react/jsx-props-no-spreading': [
'error',
{
explicitSpread: 'ignore',
},
],
// React hooks rules
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': [
'warn',
{
additionalHooks: 'useRecoilCallback',
},
],
},
},
// TypeScript specific configuration
{
files: ['**/*.{ts,tsx}'],
languageOptions: {
parser: typescriptParser,
parserOptions: {
ecmaFeatures: {
jsx: true,
},
// Note: project path should be specified by each package individually
},
},
plugins: {
'@typescript-eslint': typescriptEslint,
},
rules: {
// Import restrictions
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['@tabler/icons-react'],
message: 'Please import icons from `twenty-ui`',
},
{
group: ['react-hotkeys-web-hook'],
importNames: ['useHotkeys'],
message: 'Please use the custom wrapper: `useScopedHotkeys` from `twenty-ui`',
},
{
group: ['lodash'],
message: "Please use the standalone lodash package (for instance: `import groupBy from 'lodash.groupby'` instead of `import { groupBy } from 'lodash'`)",
},
],
},
],
// TypeScript rules
'no-redeclare': 'off', // Turn off base rule for TypeScript
'@typescript-eslint/no-redeclare': 'error', // Use TypeScript-aware version
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
fixStyle: 'inline-type-imports'
},
],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/no-empty-interface': [
'error',
{
allowSingleExtends: true,
},
],
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': 'off',
// Custom workspace rules
'@nx/workspace-effect-components': 'error',
'@nx/workspace-no-hardcoded-colors': 'error',
'@nx/workspace-matching-state-variable': 'error',
'@nx/workspace-sort-css-properties-alphabetically': 'error',
'@nx/workspace-styled-components-prefixed-with-styled': 'error',
'@nx/workspace-no-state-useref': 'error',
'@nx/workspace-component-props-naming': 'error',
'@nx/workspace-explicit-boolean-predicates-in-if': 'error',
'@nx/workspace-use-getLoadable-and-getValue-to-get-atoms': 'error',
'@nx/workspace-useRecoilCallback-has-dependency-array': 'error',
'@nx/workspace-no-navigate-prefer-link': 'error',
},
},
// Storybook files
{
files: ['*.stories.@(ts|tsx|js|jsx)'],
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
// JavaScript specific configuration
{
files: ['*.{js,jsx}'],
rules: {
// JavaScript-specific rules if needed
},
},
// Constants files
{
files: ['**/constants/*.ts', '**/*.constants.ts'],
rules: {
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['UPPER_CASE'],
},
],
'unicorn/filename-case': [
'warn',
{
cases: {
pascalCase: true,
},
},
],
'@nx/workspace-max-consts-per-file': ['error', { max: 1 }],
},
},
// Test files
{
files: [
'*.test.@(ts|tsx|js|jsx)',
],
languageOptions: {
globals: {
jest: true,
describe: true,
it: true,
expect: true,
beforeEach: true,
afterEach: true,
beforeAll: true,
afterAll: true,
},
},
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
},
},
// Constants files
{
files: ['**/*.constants.ts'],
rules: {
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['UPPER_CASE'],
},
],
'unicorn/filename-case': [
'warn',
{
cases: {
pascalCase: true,
},
},
],
'@nx/workspace-max-consts-per-file': ['error', { max: 1 }],
},
},
// JSON files
{
files: ['**/*.json'],
languageOptions: {
parser: jsoncParser,
},
},
];
View File
+40 -18
View File
@@ -1,4 +1,8 @@
{
"workspaceLayout": {
"appsDir": "packages",
"libsDir": "packages"
},
"namedInputs": {
"default": ["{projectRoot}/**/*"],
"excludeStories": [
@@ -32,7 +36,7 @@
"dependsOn": ["^build"]
},
"start": {
"cache": true,
"cache": false,
"dependsOn": ["^build"]
},
"lint": {
@@ -40,14 +44,17 @@
"cache": true,
"outputs": ["{options.outputFile}"],
"options": {
"eslintConfig": "{projectRoot}/.eslintrc.cjs",
"eslintConfig": "{projectRoot}/eslint.config.mjs",
"cache": true,
"cacheLocation": "{workspaceRoot}/.cache/eslint",
"ignorePath": "{workspaceRoot}/.gitignore"
"cacheLocation": "{workspaceRoot}/.cache/eslint"
},
"configurations": {
"ci": { "cacheStrategy": "content" },
"fix": { "fix": true }
"ci": {
"cacheStrategy": "content"
},
"fix": {
"fix": true
}
},
"dependsOn": ["^build"]
},
@@ -63,8 +70,12 @@
"write": false
},
"configurations": {
"ci": { "cacheStrategy": "content" },
"fix": { "write": true }
"ci": {
"cacheStrategy": "content"
},
"fix": {
"write": true
}
},
"dependsOn": ["^build"]
},
@@ -76,7 +87,9 @@
"command": "tsc -b tsconfig.json --incremental"
},
"configurations": {
"watch": { "watch": true }
"watch": {
"watch": true
}
},
"dependsOn": ["^build"]
},
@@ -91,7 +104,7 @@
],
"outputs": ["{projectRoot}/coverage"],
"options": {
"jestConfig": "{projectRoot}/jest.config.ts",
"jestConfig": "{projectRoot}/jest.config.mjs",
"coverage": true,
"coverageReporters": ["text-summary"],
"cacheDirectory": "../../.cache/jest/{projectRoot}"
@@ -101,8 +114,12 @@
"ci": true,
"maxWorkers": 3
},
"coverage": { "coverageReporters": ["lcov", "text"] },
"watch": { "watch": true }
"coverage": {
"coverageReporters": ["lcov", "text"]
},
"watch": {
"watch": true
}
}
},
"test:e2e": {
@@ -116,7 +133,7 @@
"outputs": ["{projectRoot}/{options.output-dir}"],
"options": {
"cwd": "{projectRoot}",
"command": "VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true storybook build --test",
"command": "VITE_DISABLE_TYPESCRIPT_CHECKER=true storybook build --test",
"output-dir": "storybook-static",
"config-dir": ".storybook"
},
@@ -192,7 +209,9 @@
"checkCoverage": true
},
"configurations": {
"text": { "reporter": "text" }
"text": {
"reporter": "text"
}
}
},
"storybook:serve-and-test:static": {
@@ -215,7 +234,7 @@
"command": "nx storybook:build {projectName}",
"forwardAllArgs": false
},
"cross-var chromatic --project-token=$CHROMATIC_PROJECT_TOKEN --storybook-build-dir=storybook-static {args.ci}"
"chromatic --storybook-build-dir=storybook-static {args.ci}"
],
"parallel": false
},
@@ -246,7 +265,7 @@
"cache": true,
"inputs": [
"default",
"{workspaceRoot}/.eslintrc.js",
"{workspaceRoot}/eslint.config.mjs",
"{workspaceRoot}/tools/eslint-rules/**/*"
]
},
@@ -261,7 +280,7 @@
}
},
"installation": {
"version": "18.3.3"
"version": "22.0.3"
},
"generators": {
"@nx/react": {
@@ -294,5 +313,8 @@
}
},
"useInferencePlugins": false,
"defaultBase": "main"
"defaultBase": "main",
"tui": {
"enabled": false
}
}
+78 -220
View File
@@ -1,123 +1,34 @@
{
"private": true,
"dependencies": {
"@air/react-drag-to-select": "^5.0.8",
"@apollo/client": "^3.7.17",
"@apollo/server": "^4.7.3",
"@aws-sdk/client-lambda": "^3.614.0",
"@aws-sdk/client-s3": "^3.363.0",
"@aws-sdk/client-sts": "^3.744.0",
"@aws-sdk/credential-providers": "^3.363.0",
"@blocknote/mantine": "^0.22.0",
"@blocknote/react": "^0.22.0",
"@blocknote/server-util": "0.17.1",
"@codesandbox/sandpack-react": "^2.13.5",
"@dagrejs/dagre": "^1.1.2",
"@date-fns/tz": "^1.4.1",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@envelop/on-resolve": "^4.1.0",
"@floating-ui/react": "^0.24.3",
"@google-cloud/local-auth": "2.1.0",
"@graphiql/plugin-explorer": "^1.0.2",
"@graphql-tools/schema": "^10.0.0",
"@hello-pangea/dnd": "^16.2.0",
"@hookform/resolvers": "^3.1.1",
"@jsdevtools/rehype-toc": "^3.0.2",
"@linaria/core": "^6.2.0",
"@linaria/react": "^6.2.1",
"@mdx-js/react": "^3.0.0",
"@microsoft/microsoft-graph-client": "^3.0.7",
"@nestjs/apollo": "^11.0.5",
"@nestjs/axios": "^3.0.1",
"@nestjs/cli": "^9.0.0",
"@nestjs/common": "^9.0.0",
"@nestjs/config": "^2.3.2",
"@nestjs/core": "^9.0.0",
"@nestjs/event-emitter": "^2.0.3",
"@nestjs/jwt": "^10.0.3",
"@nestjs/passport": "^9.0.3",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/serve-static": "^4.0.1",
"@nestjs/terminus": "^11.0.0",
"@nestjs/typeorm": "^10.0.0",
"@nx/eslint-plugin": "^17.2.8",
"@octokit/graphql": "^7.0.2",
"@ptc-org/nestjs-query-core": "^4.2.0",
"@ptc-org/nestjs-query-typeorm": "4.2.1-alpha.2",
"@react-email/components": "0.0.32",
"@react-email/render": "0.0.17",
"@sentry/node": "^8",
"@sentry/profiling-node": "^8",
"@sentry/react": "^8",
"@radix-ui/colors": "^3.0.0",
"@sentry/profiling-node": "^9.26.0",
"@sentry/react": "^9.26.0",
"@sniptt/guards": "^0.2.0",
"@stoplight/elements": "^8.0.5",
"@swc/jest": "^0.2.29",
"@tabler/icons-react": "^3.31.0",
"@types/dompurify": "^3.0.5",
"@types/facepaint": "^1.2.5",
"@types/lodash.camelcase": "^4.3.7",
"@types/lodash.chunk": "^4.2.9",
"@types/lodash.merge": "^4.6.7",
"@types/lodash.pick": "^4.3.7",
"@types/nodemailer": "^6.4.14",
"@types/passport-microsoft": "^1.0.3",
"@wyw-in-js/vite": "^0.5.3",
"@xyflow/react": "^12.4.2",
"add": "^2.0.6",
"addressparser": "^1.0.1",
"afterframe": "^1.0.2",
"apollo-server-express": "^3.12.0",
"apollo-upload-client": "^17.0.0",
"@wyw-in-js/vite": "^0.7.0",
"archiver": "^7.0.1",
"axios": "^1.6.2",
"bcrypt": "^5.1.1",
"better-sqlite3": "^9.2.2",
"body-parser": "^1.20.2",
"bullmq": "^5.40.0",
"bytes": "^3.1.2",
"class-transformer": "^0.5.1",
"clsx": "^2.1.1",
"cron-validate": "^1.4.5",
"cross-env": "^7.0.3",
"css-loader": "^7.1.2",
"danger-plugin-todos": "^1.3.1",
"dataloader": "^2.2.2",
"date-fns": "^2.30.0",
"date-fns-tz": "^2.0.0",
"debounce": "^2.0.0",
"deep-equal": "^2.2.2",
"dompurify": "^3.0.11",
"dotenv-cli": "^7.2.1",
"drizzle-orm": "^0.29.3",
"esbuild-plugin-svgr": "^2.1.0",
"facepaint": "^1.2.1",
"file-type": "16.5.4",
"framer-motion": "^11.18.0",
"fuse.js": "^7.1.0",
"googleapis": "105",
"graphiql": "^3.1.1",
"graphql": "16.8.0",
"graphql-fields": "^2.0.3",
"graphql-middleware": "^6.1.35",
"graphql-rate-limit": "^3.3.0",
"graphql-scalars": "^1.23.0",
"graphql-subscriptions": "2.0.0",
"graphql-tag": "^2.12.6",
"graphql-type-json": "^0.3.2",
"graphql-upload": "^13.0.0",
"graphql-yoga": "^4.0.4",
"hex-rgb": "^5.0.0",
"iframe-resizer-react": "^1.1.0",
"immer": "^10.0.2",
"jest-mock-extended": "^3.0.4",
"js-cookie": "^3.0.5",
"js-levenshtein": "^1.1.6",
"json-2-csv": "^5.4.0",
"jsonwebtoken": "^9.0.0",
"immer": "^10.1.1",
"libphonenumber-js": "^1.10.26",
"lodash.camelcase": "^4.3.0",
"lodash.chunk": "^4.2.0",
"lodash.compact": "^3.0.1",
"lodash.debounce": "^4.0.8",
"lodash.escaperegexp": "^4.1.2",
"lodash.groupby": "^4.6.0",
"lodash.identity": "^3.0.0",
@@ -128,137 +39,85 @@
"lodash.mapvalues": "^4.6.0",
"lodash.merge": "^4.6.2",
"lodash.omit": "^4.5.0",
"lodash.pick": "^4.4.0",
"lodash.pickby": "^4.6.0",
"lodash.snakecase": "^4.1.1",
"lodash.upperfirst": "^4.3.1",
"luxon": "^3.3.0",
"microdiff": "^1.3.2",
"moize": "^6.1.6",
"nest-commander": "^3.12.0",
"next": "14.0.4",
"next-mdx-remote": "^4.4.1",
"nodemailer": "^6.9.8",
"openapi-types": "^12.1.3",
"overlayscrollbars": "^2.6.1",
"overlayscrollbars-react": "^0.5.4",
"passport": "^0.7.0",
"passport-google-oauth20": "^2.0.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"passport-microsoft": "^2.0.0",
"patch-package": "^8.0.0",
"pg": "^8.11.3",
"pg-boss": "^9.0.3",
"planer": "^1.2.0",
"pluralize": "^8.0.0",
"prettier": "^3.0.3",
"prism-react-renderer": "^2.1.0",
"qs": "^6.11.2",
"react": "^18.2.0",
"react-data-grid": "7.0.0-beta.13",
"react-datepicker": "^6.7.1",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-error-boundary": "^4.0.11",
"react-helmet-async": "^1.3.0",
"react-hook-form": "^7.45.1",
"react-hotkeys-hook": "^4.4.4",
"react-icons": "^4.12.0",
"react-imask": "^7.6.0",
"react-intersection-observer": "^9.15.1",
"react-loading-skeleton": "^3.3.1",
"react-phone-number-input": "^3.3.4",
"react-responsive": "^9.0.2",
"react-router-dom": "^6.4.4",
"react-textarea-autosize": "^8.4.1",
"react-tooltip": "^5.13.1",
"recoil": "^0.7.7",
"rehype-slug": "^6.0.0",
"remark-behead": "^3.1.0",
"remark-gfm": "^3.0.1",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
"scroll-into-view": "^1.16.2",
"semver": "^7.5.4",
"sharp": "^0.32.1",
"slash": "^5.1.0",
"stripe": "^17.3.1",
"storybook-addon-mock-date": "^0.6.0",
"ts-key-enum": "^2.0.12",
"tslib": "^2.3.0",
"tsup": "^8.2.4",
"tslib": "^2.8.1",
"type-fest": "4.10.1",
"typescript": "5.3.3",
"use-context-selector": "^2.0.0",
"use-debounce": "^10.0.0",
"typescript": "5.9.2",
"uuid": "^9.0.0",
"vite-tsconfig-paths": "^4.2.1",
"xlsx-ugnis": "^0.19.3",
"zod": "3.23.8"
"zod": "^4.1.11"
},
"devDependencies": {
"@babel/core": "^7.14.5",
"@babel/preset-react": "^7.14.5",
"@babel/preset-typescript": "^7.24.6",
"@crxjs/vite-plugin": "^1.0.14",
"@chromatic-com/storybook": "^3",
"@graphql-codegen/cli": "^3.3.1",
"@graphql-codegen/client-preset": "^4.1.0",
"@graphql-codegen/typescript": "^3.0.4",
"@graphql-codegen/typescript-operations": "^3.0.4",
"@graphql-codegen/typescript-react-apollo": "^3.3.7",
"@microsoft/microsoft-graph-types": "^2.40.0",
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@next/eslint-plugin-next": "^14.1.4",
"@nx/eslint": "18.3.3",
"@nx/eslint-plugin": "18.3.3",
"@nx/jest": "18.3.3",
"@nx/js": "18.3.3",
"@nx/react": "18.3.3",
"@nx/storybook": "18.3.3",
"@nx/vite": "18.3.3",
"@nx/web": "18.3.3",
"@playwright/test": "^1.46.0",
"@sentry/types": "^7.109.0",
"@storybook/addon-actions": "^7.6.3",
"@nx/eslint": "22.0.3",
"@nx/eslint-plugin": "22.0.3",
"@nx/jest": "22.0.3",
"@nx/js": "22.0.3",
"@nx/react": "22.0.3",
"@nx/storybook": "22.0.3",
"@nx/vite": "22.0.3",
"@nx/web": "22.0.3",
"@sentry/types": "^8",
"@storybook/addon-actions": "8.6.14",
"@storybook/addon-coverage": "^1.0.0",
"@storybook/addon-essentials": "^7.6.7",
"@storybook/addon-interactions": "^7.6.7",
"@storybook/addon-links": "^7.6.7",
"@storybook/addon-onboarding": "^1.0.10",
"@storybook/blocks": "^7.6.3",
"@storybook/core-server": "7.6.3",
"@storybook/addon-essentials": "8.6.14",
"@storybook/addon-interactions": "8.6.14",
"@storybook/addon-links": "8.6.14",
"@storybook/blocks": "8.6.14",
"@storybook/core-server": "8.6.14",
"@storybook/icons": "^1.2.9",
"@storybook/jest": "^0.2.3",
"@storybook/react": "^7.6.3",
"@storybook/react-vite": "^7.6.3",
"@storybook/test": "^7.6.3",
"@storybook/test-runner": "^0.16.0",
"@storybook/testing-library": "^0.2.2",
"@storybook/preview-api": "8.6.14",
"@storybook/react": "8.6.14",
"@storybook/react-vite": "8.6.14",
"@storybook/test": "8.6.14",
"@storybook/test-runner": "^0.23.0",
"@storybook/types": "8.6.14",
"@stylistic/eslint-plugin": "^1.5.0",
"@swc-node/register": "1.8.0",
"@swc/cli": "^0.3.12",
"@swc/core": "1.7.42",
"@swc/core": "1.13.3",
"@swc/helpers": "~0.5.2",
"@testing-library/jest-dom": "^6.1.5",
"@testing-library/react": "14.0.0",
"@swc/jest": "^0.2.39",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@types/addressparser": "^1.0.3",
"@types/apollo-upload-client": "^17.0.2",
"@types/bcrypt": "^5.0.0",
"@types/better-sqlite3": "^7.6.8",
"@types/bytes": "^3.1.1",
"@types/chrome": "^0.0.267",
"@types/deep-equal": "^1.0.1",
"@types/express": "^4.17.13",
"@types/file-saver": "^2.0.7",
"@types/fs-extra": "^11.0.4",
"@types/graphql-fields": "^1.3.6",
"@types/graphql-upload": "^8.0.12",
"@types/js-cookie": "^3.0.3",
"@types/js-levenshtein": "^1.1.3",
"@types/inquirer": "^9.0.9",
"@types/jest": "^30.0.0",
"@types/lodash.camelcase": "^4.3.7",
"@types/lodash.compact": "^3.0.9",
"@types/lodash.debounce": "^4.0.7",
"@types/lodash.escaperegexp": "^4.1.9",
"@types/lodash.groupby": "^4.6.9",
"@types/lodash.identity": "^3.0.9",
@@ -271,101 +130,96 @@
"@types/lodash.pickby": "^4.6.9",
"@types/lodash.snakecase": "^4.1.7",
"@types/lodash.upperfirst": "^4.3.7",
"@types/luxon": "^3.3.0",
"@types/ms": "^0.7.31",
"@types/node": "18.19.26",
"@types/node": "^24.0.0",
"@types/passport-google-oauth20": "^2.0.11",
"@types/passport-jwt": "^3.0.8",
"@types/passport-microsoft": "^2.1.0",
"@types/pluralize": "^0.0.33",
"@types/react": "^18.2.39",
"@types/react-datepicker": "^6.2.0",
"@types/react-dom": "^18.2.15",
"@types/scroll-into-view": "^1.16.0",
"@types/supertest": "^2.0.11",
"@types/uuid": "^9.0.2",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/experimental-utils": "^5.62.0",
"@typescript-eslint/parser": "6.21.0",
"@typescript-eslint/utils": "6.21.0",
"@vitejs/plugin-react-swc": "^3.5.0",
"@vitest/ui": "1.4.0",
"@typescript-eslint/eslint-plugin": "^8.39.0",
"@typescript-eslint/parser": "^8.39.0",
"@typescript-eslint/utils": "^8.39.0",
"@vitejs/plugin-react-swc": "3.11.0",
"@yarnpkg/types": "^4.0.0",
"chromatic": "^6.18.0",
"concurrently": "^8.2.2",
"cross-var": "^1.1.0",
"danger": "^11.3.0",
"dotenv-cli": "^7.2.1",
"drizzle-kit": "^0.20.14",
"esbuild": "^0.23.0",
"eslint": "^8.53.0",
"eslint-config-next": "14.0.4",
"danger": "^13.0.4",
"dotenv-cli": "^7.4.4",
"esbuild": "^0.25.10",
"eslint": "^9.32.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-lingui": "^0.9.0",
"eslint-plugin-mdx": "^3.6.2",
"eslint-plugin-prefer-arrow": "^1.2.3",
"eslint-plugin-prettier": "^5.1.2",
"eslint-plugin-project-structure": "^3.9.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.4",
"eslint-plugin-simple-import-sort": "^10.0.0",
"eslint-plugin-storybook": "^0.6.15",
"eslint-plugin-unicorn": "^51.0.1",
"eslint-plugin-storybook": "^0.9.0",
"eslint-plugin-unicorn": "^56.0.1",
"eslint-plugin-unused-imports": "^3.0.0",
"http-server": "^14.1.1",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"jest-environment-jsdom": "30.0.0-beta.3",
"jest-environment-node": "^29.4.1",
"jest-fetch-mock": "^3.0.3",
"jsdom": "~22.1.0",
"msw": "^2.0.11",
"msw-storybook-addon": "2.0.0--canary.122.b3ed3b1.0",
"nx": "18.3.3",
"playwright": "^1.46.0",
"msw-storybook-addon": "^2.0.5",
"nx": "22.0.3",
"prettier": "^3.1.1",
"raw-loader": "^4.0.2",
"rimraf": "^5.0.5",
"source-map-support": "^0.5.20",
"storybook": "^7.6.3",
"storybook": "8.6.14",
"storybook-addon-cookie": "^3.2.0",
"storybook-addon-pseudo-states": "^2.1.2",
"storybook-dark-mode": "^3.0.3",
"supertest": "^6.1.3",
"ts-jest": "^29.1.1",
"ts-loader": "^9.2.3",
"ts-node": "10.9.1",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.17.0",
"vite": "^5.4.0",
"vite-plugin-checker": "^0.6.2",
"vite": "^7.0.0",
"vite-plugin-checker": "^0.10.2",
"vite-plugin-cjs-interop": "^2.2.0",
"vite-plugin-dts": "3.8.1",
"vite-plugin-svgr": "^4.2.0",
"vitest": "1.4.0"
"vite-plugin-svgr": "^4.2.0"
},
"engines": {
"node": "^18.17.1",
"node": "^24.5.0",
"npm": "please-use-yarn",
"yarn": ">=4.0.2"
},
"license": "AGPL-3.0",
"name": "twenty",
"packageManager": "yarn@4.4.0",
"packageManager": "yarn@4.9.2",
"resolutions": {
"graphql": "16.8.0",
"graphql": "16.8.1",
"type-fest": "4.10.1",
"typescript": "5.3.3",
"prosemirror-model": "1.23.0",
"yjs": "13.6.18"
"typescript": "5.9.2",
"graphql-redis-subscriptions/ioredis": "^5.6.0",
"prosemirror-view": "1.40.0",
"prosemirror-transform": "1.10.4"
},
"version": "0.2.1",
"nx": {},
"scripts": {
"docs:generate": "tsx packages/twenty-docs/scripts/generate-docs-json.ts",
"docs:generate-navigation-template": "tsx packages/twenty-docs/scripts/generate-navigation-template.ts",
"start": "npx concurrently --kill-others 'npx nx run-many -t start -p twenty-server twenty-front' 'npx wait-on tcp:3000 && npx nx run twenty-server:worker'"
},
"workspaces": {
"packages": [
"packages/twenty-chrome-extension",
"packages/twenty-front",
"packages/twenty-server",
"packages/twenty-emails",
@@ -373,8 +227,12 @@
"packages/twenty-utils",
"packages/twenty-zapier",
"packages/twenty-website",
"packages/twenty-docs",
"packages/twenty-e2e-testing",
"packages/twenty-shared",
"packages/twenty-sdk",
"packages/twenty-apps",
"packages/twenty-cli",
"tools/eslint-rules"
]
}
+1
View File
@@ -0,0 +1 @@
generated
@@ -0,0 +1,6 @@
TWENTY_API_KEY=<SET_YOUR_TWENTY_API>
DAYS_AGO=<SET_YOUR_DAYS_AGO>
DISCORD_WEBHOOK_URL=<SET_YOUR_DISCORD_WEBHOOK_URL>
FB_GRAPH_TOKEN=<SET_YOUR_FB_GRAPH_TOKEN>
WHATSAPP_RECIPIENT_PHONE_NUMBER=<SET_YOUR_WHATSAPP_RECIPIENT_PHONE_NUMBER>
SLACK_HOOK_URL=<SET_YOUR_SLACK_HOOK_URL>
@@ -0,0 +1,2 @@
.yarn/install-state.gz
.env
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
yarnPath: .yarn/releases/yarn-4.9.2.cjs
nodeLinker: node-modules
@@ -0,0 +1,108 @@
# Twenty CRM Activity Reporter
A TypeScript-based reporting bot that summarizes activity from your Twenty CRM workspace and sends daily/periodic reports to Slack, Discord, and WhatsApp. Meet Kylian Mbaguette, your friendly CRM activity reporter!
## Features
- 🧑‍💻 **People & Company Tracking**: Summarizes newly created people and companies
- 🎯 **Opportunity Monitoring**: Reports on new opportunities created, broken down by stage
-**Task Analytics**:
- Tracks task creation
- Calculates on-time completion rates
- Identifies team members with the most overdue tasks (the "slackers")
- 🔔 **Multi-Platform Notifications**: Send reports to Slack, Discord, and/or WhatsApp
-**Configurable Time Range**: Look back any number of days
## Prerequisites
- Node.js (v14 or higher recommended)
- TypeScript
- A [Twenty CRM](https://twenty.com) account with API access
- Optional: Slack webhook, Discord webhook, and/or WhatsApp Business API access
## Installing dependencies
```bash
# Install dependencies
yarn install
```
### Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `TWENTY_API_KEY` | ✅ Yes | Your Twenty CRM API key |
| `DAYS_AGO` | ✅ Yes | Number of days to look back for the report |
| `SLACK_HOOK_URL` | ❌ No | Slack incoming webhook URL |
| `DISCORD_WEBHOOK_URL` | ❌ No | Discord webhook URL |
| `FB_GRAPH_TOKEN` | ❌ No | Facebook Graph API token for WhatsApp |
| `WHATSAPP_RECIPIENT_PHONE_NUMBER` | ❌ No | WhatsApp recipient phone number (with country code) |
## Project Structure
```
.
├── index.ts # Main entry point
├── people-creation-summariser.ts # Summarizes people/company creation
├── opportunity-creation-summariser.ts # Summarizes opportunity creation
├── task-creation-summariser.ts # Summarizes task creation & completion
├── senders.ts # Handles sending to Slack/Discord/WhatsApp
├── utils.ts # API request utility
└── README.md
```
## How It Works
1. **Data Collection**: The bot queries the Twenty CRM API for activities within the specified time range
2. **Analysis**:
- Counts new people and companies
- Categorizes opportunities by stage
- Calculates task completion rates and identifies overdue tasks
3. **Reporting**: Formats the data into friendly messages
4. **Distribution**: Sends reports to configured platforms (Slack, Discord, WhatsApp)
## Report Format
Each report includes:
```
Bonjour! 🥖 Je m'appelle Kylian Mbaguette. Over the last X days:
🧑‍💻 People & Companies
- X People and Y Companies were added
🎯 Opportunities
- X Opportunities were added: Y in NEW, Z in PROPOSAL
📋 Tasks
- X Tasks were created
- Y% Tasks were completed on time
- [Name] slacked the most with Z Tasks overdue
```
## API Integration
This bot uses the [Twenty CRM REST API](https://api.twenty.com/rest/). The following endpoints are used:
- `GET /people` - Fetch people data
- `GET /opportunities` - Fetch opportunity data
- `GET /tasks` - Fetch task data
- `GET /workspaceMembers/{id}` - Fetch workspace member details
## Notes
- The "slacker" detection is lighthearted and identifies team members with the most overdue tasks
- At least one messaging platform must be configured for the bot to send reports
- The bot uses ISO date format (YYYY-MM-DD) for date filtering
- Task completion percentage only considers incomplete tasks (excludes already completed tasks from the calculation)
## Troubleshooting
**Issue**: No messages being sent
- **Solution**: Ensure at least one messaging platform is configured with valid credentials
**Issue**: API authentication errors
- **Solution**: Verify your `TWENTY_API_KEY` is correct and has necessary permissions
**Issue**: WhatsApp messages not sending
- **Solution**: Ensure both `FB_GRAPH_TOKEN` and `WHATSAPP_RECIPIENT_PHONE_NUMBER` are set correctly
## Contributing
Built with ❤️ and 🥖 by Azmat, Ali and Mike from 9dots
@@ -0,0 +1,45 @@
import { type ApplicationConfig } from 'twenty-sdk/application';
const config: ApplicationConfig = {
universalIdentifier: 'b53627f5-ca60-478c-bc43-c7ab4904e34a',
displayName: 'Activity Summary',
description:
'A TypeScript-based reporting bot that summarizes activity from your Twenty CRM workspace and sends daily/periodic reports to Slack, Discord, and WhatsApp. Meet Kylian Mbaguette, your friendly CRM activity reporter!',
applicationVariables: {
TWENTY_API_KEY: {
universalIdentifier: '304b7d5d-e2bb-4444-9b04-6b3ae8b73730',
description: 'Twenty API Key',
isSecret: true,
},
DAYS_AGO: {
universalIdentifier: '040a3097-9cee-4f74-b957-c2f9bf636c3f',
description:
'How far back into the past we want to summarise defaults to the past 7 days',
value: '7',
isSecret: false,
},
SLACK_HOOK_URL: {
universalIdentifier: 'fd16e370-934c-4267-83b4-7d88259bf7e1',
description: 'Slack hook URL for sending message to channel',
isSecret: true,
},
DISCORD_WEBHOOK_URL: {
universalIdentifier: 'f3741075-d525-4988-ba42-55d519c6fd76',
description:
'Discord webhook URL for sending message to channel of a server',
isSecret: true,
},
FB_GRAPH_TOKEN: {
universalIdentifier: 'fb907f49-74ac-4aa5-ba45-cfc9250ecc44',
description: 'For Facebook auth',
isSecret: true,
},
WHATSAPP_RECIPIENT_PHONE_NUMBER: {
universalIdentifier: 'c856ee5d-44bf-42f4-9a39-2553a94af518',
description: 'Phone number for receiving WhatsApp message',
isSecret: true,
},
},
};
export default config;
@@ -0,0 +1,17 @@
{
"name": "activity-summary",
"version": "0.0.1",
"license": "MIT",
"engines": {
"node": "^24.5.0",
"npm": "please-use-yarn",
"yarn": ">=4.0.2"
},
"packageManager": "yarn@4.9.2",
"dependencies": {
"twenty-sdk": "0.0.3"
},
"devDependencies": {
"@types/node": "^24.7.2"
}
}
@@ -0,0 +1,80 @@
import { summariseOpportunityCreation } from './opportunity-creation-summariser';
import { summarisePeopleCreation } from './people-creation-summariser';
import { sendToDiscord, sendToSlack, sendToWhatsApp } from './senders';
import { summariseTaskCreation } from './task-creation-summariser';
import { type ServerlessFunctionConfig } from 'twenty-sdk/application';
export const main = async (): Promise<object> => {
let date: string | Date = new Date();
date.setDate(new Date().getDate() - Number(process.env.DAYS_AGO));
date = date.toISOString().substring(0, 10);
const peopleCreationSummary = await summarisePeopleCreation(date);
const opportunityCreationSummary = await summariseOpportunityCreation(date);
const taskCreationSummary = await summariseTaskCreation(date);
let body = {
daysAgo: Number(process.env.DAYS_AGO),
peopleCreationSummary,
opportunityCreationSummary,
taskCreationSummary,
discord: {},
whatsapp: {},
slack: {},
};
if (process.env.SLACK_HOOK_URL) {
const slackBody = await sendToSlack({
peopleCreationSummary,
opportunityCreationSummary,
taskCreationSummary,
});
body = {
...body,
slack: slackBody,
};
}
if (process.env.DISCORD_WEBHOOK_URL) {
const discordBody = await sendToDiscord({
peopleCreationSummary,
opportunityCreationSummary,
taskCreationSummary,
});
body = {
...body,
discord: discordBody,
};
}
if (
process.env.FB_GRAPH_TOKEN &&
process.env.WHATSAPP_RECIPIENT_PHONE_NUMBER
) {
const whatsappBody = await sendToWhatsApp({
peopleCreationSummary,
opportunityCreationSummary,
taskCreationSummary,
});
body = {
...body,
whatsapp: whatsappBody,
};
}
return body;
};
export const config: ServerlessFunctionConfig = {
universalIdentifier: 'c5b0e3f7-cbbd-4bd6-b01c-150d52cf2ce9',
name: 'summarise-and-send',
triggers: [
{
universalIdentifier: '36e1c4c7-8664-4d6d-a88f-ac56f1bd0651',
type: 'cron',
pattern: '0 9 * * *',
},
],
};
@@ -0,0 +1,28 @@
import { request } from "./utils"
type Opportunity = {
stage: 'NEW' | 'PROPOSAL'
}
export const summariseOpportunityCreation = async (date: string) => {
const { opportunities }: { opportunities: Opportunity[] } = await request(
`opportunities?filter=createdAt[gte]:${date}`,
)
if (opportunities.length === 0) {
return `- No Opportunities were added`
}
const stageSummary = Object.entries(
opportunities.reduce((hash: Record<string,number>, opportunity) => {
if (!hash[opportunity.stage]) {
hash[opportunity.stage] = 0
}
hash[opportunity.stage] += 1
return hash
}, {})
).map(([stage, value]) => `${value} in ${stage}`).join(', ')
return `- ${opportunities.length} Opportunities were added: ${stageSummary}`
}
@@ -0,0 +1,38 @@
import { request } from "./utils"
type Person = {
companyId: string
company: Company
}
type Company = {
id: string
accountOwnerId: string
}
export const summarisePeopleCreation = async (date: string) => {
const { people }: { people: Person[] } = await request(
`people?depth=1&filter=createdAt[gte]:${date}`,
)
if (people.length === 0) {
return '- No People were added'
}
let createdForCompanies: Record<string, Company> = {}
let numberOfAccountOwnerlessCompanies = 0
for (const person of people) {
const isCompanyTracked = createdForCompanies[person.companyId]
if (person.companyId && !isCompanyTracked) {
createdForCompanies[person.company.id] = person.company
if (!person?.company?.accountOwnerId) {
numberOfAccountOwnerlessCompanies += 1
}
}
}
return `- ${people.length} People were added for ${Object.keys(createdForCompanies).length} Companies
- Out of those, ${numberOfAccountOwnerlessCompanies} Companies don't have account owners yet`
}
@@ -0,0 +1,172 @@
export const sendToSlack = async (params: {
peopleCreationSummary: string;
opportunityCreationSummary: string;
taskCreationSummary: string;
}) => {
const {
peopleCreationSummary,
opportunityCreationSummary,
taskCreationSummary,
} = params;
const slackMessage = {
blocks: [
{
type: 'header',
text: {
type: 'plain_text',
text: `Bonjour! 🥖 Je m'appelle Kylian Mbaguette. Over the last ${process.env.DAYS_AGO} days`,
emoji: true,
},
},
{
type: 'header',
text: {
type: 'plain_text',
text: '🧑‍💻 People & Companies',
emoji: true,
},
},
{
type: 'section',
text: {
type: 'plain_text',
text: peopleCreationSummary,
emoji: true,
},
},
{
type: 'header',
text: {
type: 'plain_text',
text: '🎯 Opportunities',
emoji: true,
},
},
{
type: 'section',
text: {
type: 'plain_text',
text: opportunityCreationSummary,
emoji: true,
},
},
{
type: 'header',
text: {
type: 'plain_text',
text: '📋 Tasks',
emoji: true,
},
},
{
type: 'section',
text: {
type: 'plain_text',
text: taskCreationSummary,
emoji: true,
},
},
],
};
const response = await fetch(process.env.SLACK_HOOK_URL ?? '', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(slackMessage),
});
return {
formattedMessage: slackMessage,
webhookStatus: response.status,
};
};
export const sendToDiscord = async (params: {
peopleCreationSummary: string;
opportunityCreationSummary: string;
taskCreationSummary: string;
}) => {
const {
peopleCreationSummary,
opportunityCreationSummary,
taskCreationSummary,
} = params;
const formattedMessage = `Bonjour! 🥖 Je m'appelle Kylian Mbaguette. Over the last ${process.env.DAYS_AGO} days:
**🧑‍💻 People & Companies**
${peopleCreationSummary}
**🎯 Opportunities**
${opportunityCreationSummary}
**📋 Tasks**
${taskCreationSummary}`;
const body = {
username: 'Twenty Bot',
content: formattedMessage,
};
const response = await fetch(process.env.DISCORD_WEBHOOK_URL ?? '', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
return {
formattedMessage,
webhookStatus: response.status,
};
};
export const sendToWhatsApp = async (params: {
peopleCreationSummary: string;
opportunityCreationSummary: string;
taskCreationSummary: string;
}): Promise<object> => {
const {
peopleCreationSummary,
opportunityCreationSummary,
taskCreationSummary,
} = params;
const formattedMessage = `Bonjour! 🥖 Je m'appelle Kylian Mbaguette. Over the last ${process.env.DAYS_AGO} days:
*🧑‍💻 People & Companies*
${peopleCreationSummary}
*🎯 Opportunities*
${opportunityCreationSummary}
*📋 Tasks*
${taskCreationSummary}`;
const response = await fetch(
'https://graph.facebook.com/v22.0/828771160324576/messages',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.FB_GRAPH_TOKEN}`,
},
body: JSON.stringify({
messaging_product: 'whatsapp',
recipient_type: 'individual',
to: process.env.WHATSAPP_RECIPIENT_PHONE_NUMBER,
type: 'text',
text: {
preview_url: true,
body: formattedMessage,
},
}),
},
);
const responseBody = await response.json();
return {
formattedMessage,
webhookStatus: response.status,
webhookResponse: responseBody,
};
};
@@ -0,0 +1,89 @@
import { request } from "./utils"
type Task = {
status: string
dueAt: string
createdBy: {
workspaceMemberId: string
}
}
export const summariseTaskCreation = async (date: string) => {
const { tasks }: { tasks: Task[] } = await request(
`tasks?filter=createdAt[gte]:${date}`,
)
if (tasks.length === 0) {
return '- No Tasks were added'
}
const presentDateISOString = new Date().toISOString()
const workspaceMemberIdsDueDateCounter: Record<string, number> = {}
let workspaceMembers = []
tasks.forEach((task) => {
if (task.status === 'DONE') {
return
}
if (presentDateISOString >= task.dueAt) {
if (!workspaceMemberIdsDueDateCounter[task.createdBy.workspaceMemberId]) {
workspaceMemberIdsDueDateCounter[task.createdBy.workspaceMemberId] = 0
}
workspaceMemberIdsDueDateCounter[task.createdBy.workspaceMemberId] += 1
}
})
for (const { userId, count } of findMaxIncompleteKeys(workspaceMemberIdsDueDateCounter)) {
const data = await request(`workspaceMembers/${userId}`)
if (data.workspaceMember) {
workspaceMembers.push({
...data.workspaceMember,
slackCount: count
})
}
}
let slackerMessage = workspaceMembers.length > 0 ? workspaceMembers.reduce((text, member, index) => {
if (index === 0 && workspaceMembers.length === 1) {
return `${member.name.firstName} slacked the most with ${member.slackCount} Tasks overdue`
}
if (index !== workspaceMembers.length - 1) {
return text.concat(`, ${member.name.firstName}`)
}
if (index === workspaceMembers.length - 1) {
return text.concat(`, and ${member.name.firstName} slacked the most with ${member.slackCount} Tasks overdue`)
}
}, '') : 'No one was caught slacking!'
const tasksCompletedOnTime = tasks.filter(
task => task.status === 'DONE' && task.dueAt >= presentDateISOString
)
const taskCompletionPercentage = tasksCompletedOnTime.length > 0
? (tasksCompletedOnTime.length / tasks.length) * 100
: NaN
const taskCompletionMessage = isNaN(taskCompletionPercentage)
? 'No completed Tasks yet'
: `${taskCompletionPercentage.toFixed(2)}% of Tasks were completed on time`
return `- ${tasks.length} Tasks were created
- ${taskCompletionMessage}
- ${slackerMessage}`
}
/**
* @description This is generated by AI
*/
const findMaxIncompleteKeys = (workspaceMemberIdsDueDateCounter: Record<string,number>) => {
// Get the maximum incomplete count
const max = Math.max(...Object.values(workspaceMemberIdsDueDateCounter));
// Filter keys that match the maximum value
return Object.entries(workspaceMemberIdsDueDateCounter)
.filter(([_, count]) => count === max)
.map(([userId, count]) => ({ userId, count }))
};
@@ -0,0 +1,13 @@
export const request = async (route: string, authToken?: string) => {
const response = await fetch(
`https://api.twenty.com/rest/${route}`,
{
headers: {
Authorization: `Bearer ${process.env.TWENTY_API_KEY}`
},
}
)
const json = await response.json()
return json.data
}
@@ -0,0 +1,26 @@
{
"compileOnSave": false,
"compilerOptions": {
"sourceMap": true,
"declaration": true,
"outDir": "./dist",
"rootDir": ".",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"strict": true,
"target": "es2018",
"module": "esnext",
"lib": ["es2020", "dom"],
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"resolveJsonModule": true
},
"exclude": [
"node_modules",
"dist",
"**/*.test.ts",
"**/*.spec.ts"
]
}
@@ -0,0 +1,38 @@
# This file is generated by running "yarn install" inside your project.
# Manual changes might be lost - proceed with caution!
__metadata:
version: 8
cacheKey: 10c0
"@types/node@npm:^24.7.2":
version: 24.9.2
resolution: "@types/node@npm:24.9.2"
dependencies:
undici-types: "npm:~7.16.0"
checksum: 10c0/7905d43f65cee72ef475fe76316e10bbf6ac5d08a7f0f6c38f2b6285d7ca3009e8fcafc8f8a1d2bf3f55889c9c278dbb203a9081fd0cf2d6d62161703924c6fa
languageName: node
linkType: hard
"activity-summary@workspace:.":
version: 0.0.0-use.local
resolution: "activity-summary@workspace:."
dependencies:
"@types/node": "npm:^24.7.2"
twenty-sdk: "npm:0.0.3"
languageName: unknown
linkType: soft
"twenty-sdk@npm:0.0.3":
version: 0.0.3
resolution: "twenty-sdk@npm:0.0.3"
checksum: 10c0/0a3c85c27edb22fb50f7eb0da4f9770e85729fce05e9e0118ad0cdfc36e42425c93340a6cd1c276daf30aeeaa612db0cd905831c0a8287a31bff3da5be9b0562
languageName: node
linkType: hard
"undici-types@npm:~7.16.0":
version: 7.16.0
resolution: "undici-types@npm:7.16.0"
checksum: 10c0/3033e2f2b5c9f1504bdc5934646cb54e37ecaca0f9249c983f7b1fc2e87c6d18399ebb05dc7fd5419e02b2e915f734d872a65da2e3eeed1813951c427d33cc9a
languageName: node
linkType: hard
@@ -0,0 +1,19 @@
# Set environment values for your application here.
# Use the format: KEY=value
#
# These variables are automatically loaded when running your serverless functions.
# You can access them directly in your code using:
# const myValue = process.env.KEY;
#
# To make these variables available to your application,
# add them to package.json "env" key. This "env" key defines all
# environment variables that will be provided to your serverless
# functions at runtime.
#
# Example:
# API_TOKEN=your-api-token
# TIMEOUT_MS=3000
TWENTY_API_URL=
TWENTY_API_KEY=
OPENAI_API_KEY=
@@ -0,0 +1,2 @@
.yarn/install-state.gz
.env
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
yarnPath: .yarn/releases/yarn-4.9.2.cjs
nodeLinker: node-modules
@@ -0,0 +1,159 @@
# AI Meeting Transcript
Automatically process meeting transcripts to extract insights, action items, and follow-ups using AI.
## Features
- **Automatic Transcript Processing**: Receives meeting transcripts via webhook from Granola or similar transcription tools
- **AI-Powered Analysis**: Uses OpenAI to extract:
- Meeting summary
- Key discussion points
- Action items with assignees and due dates
- Commitments made by participants
- **Rich Note Creation**: Creates formatted notes in Twenty with summary and key points
- **Task Generation**: Automatically creates tasks for action items and commitments, linked to the meeting note
## Requirements
- `twenty-cli` - Install globally: `npm install -g twenty-cli`
- `apiKey` - Go to `https://twenty.com/settings/api-webhooks` to generate one
- `OpenAI API Key` - Get your API key from [OpenAI](https://platform.openai.com/api-keys)
## Installation
1. Copy the environment file:
```bash
cp .env.example .env
```
2. Edit `.env` and replace the placeholders:
- `<SET_YOUR_TWENTY_API>` with your Twenty API key
- `<SET_YOUR_OPENAI_API_KEY>` with your OpenAI API key
3. Install dependencies:
```bash
yarn install
```
4. Sync the app to your Twenty workspace:
```bash
twenty auth login
twenty app sync
```
## Configuration
After syncing, configure the environment variables in your Twenty workspace:
1. Go to Settings → Apps → AI Meeting Transcript
2. Set the following environment variables:
- `TWENTY_API_KEY` - Your Twenty API key
- `TWENTY_API_URL` - Your Twenty instance URL (e.g., `https://api.twenty.com` or `http://localhost:3000` for local development)
- `OPENAI_API_KEY` - Your OpenAI API key
**Important**: `TWENTY_API_URL` is required and must be set to your Twenty instance URL. For local development, use `http://localhost:3000`. For production, use your actual Twenty instance URL.
## Usage
### Webhook Endpoint
The app exposes a public serverless route trigger.
```
POST /s/webhook/transcript
```
Examples:
- Local: `POST http://localhost:3000/s/webhook/transcript`
- Hosted: `POST https://your-twenty-instance.com/s/webhook/transcript`
### Webhook Payload Format
Send a POST request with the following JSON structure:
```json
{
"transcript": "Full meeting transcript text here...",
"meetingTitle": "Q4 Planning Meeting",
"meetingDate": "2024-01-15",
"participants": ["John Doe", "Jane Smith"],
"metadata": {
"duration": "45 minutes",
"location": "Conference Room A"
}
}
```
**Required Fields:**
- `transcript` (string): The full meeting transcript text
**Optional Fields:**
- `meetingTitle` (string): Title of the meeting
- `meetingDate` (string): Date of the meeting (ISO format or readable date)
- `participants` (string[]): List of meeting participants
- `metadata` (object): Additional metadata about the meeting
### Example Webhook Call
```bash
curl -X POST https://your-twenty-instance.com/s/webhook/transcript \
-H "Content-Type: application/json" \
-d '{
"transcript": "John: Let'\''s start the meeting. Today we need to discuss Q4 goals. Jane: I agree. We should focus on customer retention. John: Great point. Can you prepare a report by Friday? Jane: Yes, I will have it ready.",
"meetingTitle": "Q4 Planning Meeting",
"meetingDate": "2024-01-15"
}'
```
### What Happens
1. **Transcript Analysis**: The transcript is sent to OpenAI for analysis
2. **Note Creation**: A formatted note is created in Twenty with:
- Meeting summary
- Key discussion points
- Reference to the transcript source
3. **Task Creation**: Tasks are automatically created for:
- Each action item identified
- Each commitment made by participants
- Tasks include a reference to the meeting note ID in their description
## Development
Run dev mode to see application updates on your workspace instantly:
```bash
twenty app dev
```
## Integration with Granola
To integrate with Granola or similar transcription tools:
1. Set up a webhook in your transcription service
2. Configure it to POST to: `https://your-twenty-instance.com/s/webhook/transcript`
3. Map the transcription service's payload format to the expected format above
### Granola Webhook Setup
If using Granola, configure the webhook to send:
- `transcript` field with the transcript text
- Optionally include meeting metadata fields
## API Response
The webhook returns a JSON response:
```json
{
"success": true,
"noteId": "uuid-of-created-note",
"taskIds": ["uuid-of-task-1", "uuid-of-task-2"],
"summary": {
"noteCreated": true,
"tasksCreated": 2,
"actionItemsProcessed": 1,
"commitmentsProcessed": 1
}
}
```

Some files were not shown because too many files have changed in this diff Show More