Commit Graph

577 Commits

Author SHA1 Message Date
Marie 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
martmull 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
Abdul Rahman 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
Charles Bochet 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
martmull 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
Marie 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
Thomas Trompette 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
martmull 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
Guillim 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
Thomas Trompette 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
Baptiste Devessier 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
Mohit Agrawal 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 Devessier 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 Trompette 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
Abdul Rahman 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
neo773 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 Rastoin 3c5595e4ff Nitpick: psl types (#12925)
Close https://github.com/twentyhq/twenty/issues/12917
2025-06-27 14:31:27 +02:00
Etienne 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
Guillim 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
martmull f86b9b12b3 Add placeholder to generate fake form respose (#12871) 2025-06-25 17:21:17 +02:00
Guillim 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 Trompette 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
martmull ce55b20faa Use main dataSource to query CRON jobs (#12830)
As title
2025-06-24 13:29:00 +00:00
Guillim 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
Guillim 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
Charles Bochet 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
nitin 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
Guillim 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 Trompette 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
Abdul Rahman 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
Charles Bochet 24fa479cbf Fix webhook size too big (#12749) 2025-06-20 14:42:25 +02:00
martmull 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
Guillim 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
Thomas Trompette f9da3735de Remove workflow feature flag (#12732)
Removing workflows from the lab
2025-06-19 13:26:00 +00:00
Baptiste Devessier 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
Thomas Trompette 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
Guillim 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
Guillim 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
martmull 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
Félix Malfait 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
Antoine Moreaux b1af98f93d refactor(auth): add workspaces selection (#12098) 2025-06-13 16:17:35 +02:00
martmull 194549b77e Fix flaky test (#12579)
as title, add missing awaits
2025-06-13 12:33:56 +00:00
Abdul Rahman 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
Guillim 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
nitin 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
martmull 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
Marie 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
Baptiste Devessier 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
Marie 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
Marie 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