Commit Graph

346 Commits

Author SHA1 Message Date
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
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
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
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
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
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
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
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
4c94fc2803 [permissions V2] Remove feature flag (#12790) 2025-06-23 15:22:57 +00:00
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
94557e7447 Fix attachment body not being loaded (#12770)
Closes https://github.com/twentyhq/twenty/issues/12756
2025-06-20 17:50:49 +02:00
24fa479cbf Fix webhook size too big (#12749) 2025-06-20 14:42:25 +02:00
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
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
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
b1af98f93d refactor(auth): add workspaces selection (#12098) 2025-06-13 16:17:35 +02:00
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
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
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
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
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
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
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
bf3ad475f6 Fix CI lint server (#12406)
As per title
2025-06-02 12:07:51 +02:00
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
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
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
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
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
69831b17ff Signed file follow up (#12347) 2025-05-28 13:02:27 +02:00
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
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
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
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
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](1dbba8c9e2)
@thomtrp 

**2. Fix type in messagingImportExceptionHandler** 
commit [fix type issue on
messagingImportExceptionHandler](919bb3844c)
@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](57cc315efe),
[use UUIDFilter
(2)](304553d770),
[fix ids typed as UUID instead of
ID](f95d6319cf)
@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](c299b39c8f)
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](567c25495e)
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
ddab513c0b patch messages in thread (#12191)
closes https://github.com/twentyhq/twenty/issues/12190
2025-05-23 10:24:13 +00:00
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
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
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
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
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
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
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
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
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
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
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
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
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