Commit Graph

918 Commits

Author SHA1 Message Date
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
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
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
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
11abe5440b feat(ai): add mcp-metadata (#13150)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-16 21:32:32 +02:00
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
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
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
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
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
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
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
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
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
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
7e419337b5 Delete userWorkspace when removed from workspace (#13131)
Fixes https://github.com/twentyhq/twenty/issues/13024
2025-07-09 18:34:50 +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
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
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
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
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
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
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
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
a5deddaffd fieldmetadatatype + featurelfag creation (#13021)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-07-08 12:23:28 +02:00
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
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
29f7b74756 fix(ci): reorganize workflow steps and move cache saving to correct s… (#13083)
…tage
2025-07-07 16:06:25 +00:00
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
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
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
e5522c8efe feat(ai): add mcp integration (#13004) 2025-07-03 21:23:58 +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
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
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
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
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
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
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
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
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
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
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
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
ada7933f9b Import - richTextV2 import (#12868)
- Enable markdown import
- Decrease the createMany batch size on import
2025-06-26 17:02:45 +02:00