Commit Graph

1882 Commits

Author SHA1 Message Date
Thomas Trompette 6ea7aea92b Migrate update step changes to diff (#14663)
This PR should fix optimistic rendering issues on step updates:
- compute a diff for trigger and steps on mutations
- build an util that applies that diff (built a more robust version from
https://github.com/AsyncBanana/micropatch)
- apply diff in cache
2025-09-23 16:41:26 +00:00
Harshit Singh 09dd49d6d6 feat: Added workspace-level impersonation module and functionality (#14360)
## Description

- This PR is focused on issue
https://github.com/twentyhq/core-team-issues/issues/1421
- Added workspace-level impersonation apart from current
server-level-impersonation
- Introduced WorkspaceImpersonationModule, including service and
resolver for user impersonation within workspaces.
- Enhanced AdminPanelService and AdminPanelResolver to support
impersonation logic, including authentication checks and token
generation.
- added Member Management Interface in settings/members table
- added GraphQL mutation for workspace-level impersonation



## Visual Proof

<img width="919" height="444" alt="Screenshot 2025-09-09 at 1 29 22 AM"
src="https://github.com/user-attachments/assets/a361c6eb-03de-48db-b68a-7d3a489fafde"
/>


https://github.com/user-attachments/assets/454bc1aa-8b8f-4de1-9304-7c147da71dd4


## Impersontion Cookie

<img width="1792" height="297" alt="Screenshot 2025-09-11 at 9 44 06 PM"
src="https://github.com/user-attachments/assets/a8a37d5e-d38d-4472-94a7-4e4b36fba14e"
/>



<img width="1235" height="1041" alt="Screenshot 2025-09-19 at 1 24
09 AM"
src="https://github.com/user-attachments/assets/875e8f9c-e0cb-404b-8291-8fadc6c2a163"
/>

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-09-23 18:07:53 +02:00
nitin 8b2726b3fb [Dashboards] - Fix seeding not working for YC workspace because of duplicate IDs (#14591) 2025-09-23 18:01:56 +02:00
Raphaël Bosi 7cb294169d Add a new graphql mutation in the pageLayout resolver to handle page layout update with tabs and widgets (#14612)
Add a new graphql mutation in the pageLayout resolver to handle page
layout update with tabs and widgets.

Later we will add validation inside the service to check if the page
layout tab structure is correct (for instance check widgets don't
overlap or aren't out of the grid, or to check that they have a correct
configuration ...).

This mutation will be plugged to the save action of the dashboards in
the frontend.
2025-09-23 11:00:36 +02:00
Paul Rastoin fbd3286792 Index v2 side effects (#14567)
# Introduction
Honestly this implem is a mess, discussing a potential side effect
handler with @weiko before the build and run that would handle each side
effect per entity and operation

Handling:
- [ ] unique index is generated when a field is updated with the
`isUnique`
- [x] an index is generated when a relation is created
- [x] search vector index creation on custom object creation
- [x] renaming a field metadata or an object should re-create all
related indexes which are composed by their namings
- [x] delete object should remove any related indexes
- [x] delete field should update related indexes ( if index ends up
empty it should be removed )
- [ ] on object renaming that contains morph fields -> triggers update
field -> trigger index recompute
- [x] on update name renaming should recompute all related indexes

## TODO
- [x] Integration testing
- [ ] Refactor the index maps cache to be storing a
`idsByObjectMetadataId`
- [x] Refactor deterministic name to use order sorting
- [x] Remove flat index from flat object

## What's next

Will handle morph indexes in a new dedicated PR for the moment will
stick to this
Same for the cache improvement and uniqueness
2025-09-23 10:57:11 +02:00
neo773 0011864f9f Fix/preserve channels on credential update (#14633)
https://github.com/user-attachments/assets/6165f177-c32d-4ddf-8991-3986f01897ee


/closes #14522
2025-09-23 09:22:39 +02:00
Abdul Rahman 216d72b5d7 AI SDK v5 migration (#14549)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-22 22:13:43 +02:00
Weiko 40240ce514 Add view viewField favorite creation after object creation in migration v2 (#14644)
## Context
We are not exactly sure how we want to handle side effects with
workspace migration v2, in the meantime I'm re-introducing this part in
the caller (object v2 service)
2025-09-22 16:19:38 +02:00
github-actions[bot] d308f5adf9 i18n - translations (#14634)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-21 17:20:09 +02:00
Arik Chakma 9a2766feae feat: rich text email body (#14482)
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-21 16:55:34 +02:00
Abdullah. ff3467c18e feat (search): add dynamic search field metadata foundation for database-driven search configuration (#14469)
## Summary

Implements the foundation for dynamic search field configuration from
[issue #1428](https://github.com/twentyhq/core-team-issues/issues/1428).

## Changes

- Add `SearchFieldMetadataEntity` junction table for storing searchable
field configurations
- Add `SearchFieldMetadataService` with core CRUD operations  
- Add `SearchFieldMetadataModule` following existing patterns  
- Add `IS_DYNAMIC_SEARCH_FIELDS_ENABLED` feature flag (defaults to
`false`)
- Database migration with proper indexes and foreign keys  

## Architecture

Uses a junction table where **record existence = field is searchable**:

**Table: `searchFieldMetadata(objectMetadataId, fieldMetadataId,
workspaceId)`**

- Unique constraint on `(objectMetadataId, fieldMetadataId)`  
- `ON DELETE CASCADE` on foreign keys  

## Testing

- [x] Migration runs successfully  
- [x] Table created with correct schema  
- [x] Feature flag seeded properly  
- [x] Database reset works correctly  

## Next Steps

Future PRs will handle:

- Data migration from existing hardcoded search field configs  
- Integration with search services  

 No breaking changes — fully backward compatible.
2025-09-19 18:35:51 +02:00
Antoine Moreaux deed08ba25 fix(billing): reenable trial (#14616)
…reation
2025-09-19 15:16:57 +02:00
Charles Bochet 349b15e81f Add scripts to relaunch message and calendar channels (#14579)
## Context

1. We are debugging the experience on messaging and calendar sync. I'm
adding two scripts to relaunch messaging and calendar channels
2. We are seeing errors in Sentry regarding microsoft drivers errors. I
was about to fix them but I'm refactoring / simplifying a bit the logic
first. It will be a betters starting point
2025-09-19 12:31:19 +02:00
Marie 4a6ad48a62 Fix - Record text should always be visible and in first position in views (#14598)
Fixes https://github.com/twentyhq/twenty/issues/14442

Issues were
1. Table headers always used label metadata identifier (or record text)
as first column, while table body followed viewFields positions
2. Label metadata identifier should always be visible and in first
position for the table views to work as expected, while when updating
the label metadata identifier for an object, no changes were brought to
the viewFields

To fix that
1. In the BE: 
- a new logic is implemented to i) update label identifier's viewFields
position and visibility when an object's label identifier is updated to
a new field; ii) add validation on the update of a viewField's position
and visibility to make sure the label identifier's viewField always has
the lowest position + is visible
- a command was added to check all existing views and viewfields
3. In the FE: at first I tried to replicate the logic of the headers
(based on the label identifier rather than the positions) on the body,
but it was too complex and error-prone as in multiple places we are
based on the positions. It also feels more right to have only one source
of truth which is the viewField position. @lucasbordeau if that does not
suit you, we can throw an error if the field with the lowest position is
not the label metadata identifier, as you said the table view will be
very buggy / wont work if the label identifier is not in the first
position. but now it should never be the case thanks to the validation
implemented in the BE

This should be migrated to viewFieldService V2 when relevant @Weiko
@prastoin
2025-09-19 10:24:09 +00:00
Antoine Moreaux 43e0cd5d05 feat(billing): refacto billing (#14243)
… prices for metered billing

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-19 11:25:53 +02:00
Charles Bochet c7005db860 Fix sort bug issue (#14607)
Enum should not receive any special treatment when building order by
2025-09-18 20:23:19 +02:00
Paul Rastoin 235eef32f6 Improve builder return type (#14592)
We need grain in orchestrator over actions ordering for upcoming index
integration to v2
2025-09-18 12:42:01 +00:00
github-actions[bot] c582eaea4d i18n - translations (#14583)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-17 23:20:01 +02:00
Ketan Mehta dc26e48f6f fixing Numbers formatting (#14403)
fix #13880

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-09-17 23:03:33 +02:00
nitin 666b99524a remove singleton usage of i18n (#14422)
closes https://github.com/twentyhq/core-team-issues/issues/1480

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-09-17 19:01:43 +02:00
Charles Bochet f3adce0773 Fix one to many relation and multi select fields on table (#14576)
Fixes:
- relation one to many cannot be set (we have deprecated limit: keyword
in graphql at it was not use, we should only use first or last)
- https://github.com/twentyhq/twenty/issues/14556
2025-09-17 18:55:02 +02:00
github-actions[bot] 1c8dccda01 i18n - translations (#14575)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-17 17:45:43 +02:00
Thomas Trompette 8b345c9fd2 Change workflow node type (#14570)
- Update step endpoint now supports the case where node type is updated
- Added a new page for edition that re-uses the existing select action
component

Additional work:
- moved submitForm function to workflow runner service



https://github.com/user-attachments/assets/1fcb0adc-fe17-41f9-b2ea-4f84318db860
2025-09-17 15:36:42 +00:00
github-actions[bot] d841b0d0db i18n - translations (#14560)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-17 15:14:16 +02:00
Paul Rastoin 2d8669ae71 Index v2 runner (#14537)
## Introduction
https://github.com/twentyhq/twenty/pull/14363
In this PR we're creating builder and runner for index metadata
Removing its previous integration within object builder

## Next:
- implem index impact on field and object metadata api
- Add integration testing coverage add integration test on index
- Implement uniqueness toggle in field metadata api
- add integration test on uniqueness

related to https://github.com/twentyhq/core-team-issues/issues/1344
2025-09-17 13:02:43 +00:00
Etienne 24204b2928 Group By - Add feature flag (#14558)
Tested : 
- workspace needs to flush cache after activating feature flag 
- workspace does not need to flush cache if ff false and coming from
previous version (before gql schema gen updates)
2025-09-17 11:42:11 +00:00
Abdul Rahman 8d9617131c Feat: Add reasoning summary and tool details display for AI responses (#14414)
Closes [#1405](https://github.com/twentyhq/core-team-issues/issues/1405)

### Implemented Features
- Reasoning Summary: Collapsible display of AI thinking process with
real-time streaming
- Tool Execution: Detailed tool call rendering with expandable results
and loading states
- Error Handling: Clean error stream event display with proper
formatting


### Demo



https://github.com/user-attachments/assets/76ad29b7-d831-4bc8-a115-ad25f7ace6e2

<img width="504" height="819" alt="Screenshot 2025-09-12 at 3 23 39 AM"
src="https://github.com/user-attachments/assets/82dc177d-f009-4e8a-8901-ee1a49201984"
/>

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-17 11:30:24 +02:00
martmull f6530abdf4 Add settings section for public domains (#14543)
As title



https://github.com/user-attachments/assets/1c2adb14-0fc1-4623-88bc-10ff729c72a1
2025-09-17 09:07:02 +00:00
Etienne dc435a7946 Add default limit when fetching records (#14532)
- set default limit on front find many hooks
- use default constant in rest api find many endpoint
- set a max limit in rest api find many endpoint
2025-09-17 10:32:47 +02:00
Etienne 61b9d82950 create groupBy resolver + mock groupBy service (#14530)
To test :

```
query : 
query companiesGroupBy($groupBy: CompanyGroupByInput){
  companiesGroupBy(groupBy: $groupBy){
    groupByDimensionValues
    countEmptyId
    sumAnnualRecurringRevenueAmountMicros
    countEmptyAddress
    percentageEmptySearchVector
  }
}

input : 
{"groupBy": {"name": true, "employees": true, "domainName": {"primaryLinkUrl": true}}}

response : 
{
  "data": {
    "companiesGroupBy": [
      {
        "groupByDimensionValues": [
          "Text 1",
          "twenty.com",
          "1"
        ],
        "countEmptyId": 39,
        "sumAnnualRecurringRevenueAmountMicros": 20,
        "countEmptyAddress": 56,
        "percentageEmptySearchVector": 88
      },
      {
        "groupByDimensionValues": [
          "Long long long long and long text 2",
          "github.com/twentyhq/twenty",
          "2"
        ],
        "countEmptyId": 20,
        "sumAnnualRecurringRevenueAmountMicros": 56,
        "countEmptyAddress": 88,
        "percentageEmptySearchVector": 2
      },
      {
        "groupByDimensionValues": [
          "Text 3",
          "react.dev",
          "3"
        ],
        "countEmptyId": 56,
        "sumAnnualRecurringRevenueAmountMicros": 88,
        "countEmptyAddress": 2,
        "percentageEmptySearchVector": 39
      }
    ]
  }
}
```
closes https://github.com/twentyhq/core-team-issues/issues/1439
2025-09-17 10:23:34 +02:00
Abdullah. 2a7a83de81 feat(search): Add unaccent support for accent-insensitive search. (#14464)
##  Add accent-insensitive search functionality

### 🎯 Overview
Implements accent-insensitive search across all searchable fields in
Twenty CRM.
Users can now search for "jose" to find "José", "muller" to find
"Müller", "cafe" to find "café", etc.

### 🔍 Problem
Twenty's search functionality was accent-sensitive, requiring users to
type exact accented characters to find records.
This created a poor user experience, especially for international names
and content.

### 💡 Solution
Added PostgreSQL `unaccent` extension with a custom immutable wrapper
function to enable accent-insensitive full-text search across all
searchable field types.

### 📋 Changes Made
**Modified Files:**  
- `packages/twenty-server/scripts/setup-db.ts`  
-
`packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-where-condition-parts.ts`
-
`packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util.ts`

### 🗄️ Database Setup (`setup-db.ts`)
```sql
-- Added unaccent extension
CREATE EXTENSION IF NOT EXISTS "unaccent";

-- Created immutable wrapper function
CREATE OR REPLACE FUNCTION unaccent_immutable(text) RETURNS text AS $$
  SELECT public.unaccent($1)
$$ LANGUAGE sql IMMUTABLE;
```

### 🔍 Search Vector Generation
(`get-ts-vector-column-expression.util.ts`)
Applied `public.unaccent_immutable()` to all searchable field types:  
- TEXT fields (job titles, names, etc.)  
- FULL_NAME fields (first/last names)  
- EMAILS fields (both email address and domain)  
- ADDRESS fields  
- LINKS fields  
- RICH_TEXT and RICH_TEXT_V2 fields

### 🔎 Query Processing (`compute-where-condition-parts.ts`)
Enhanced search queries to use `public.unaccent_immutable()` for both:  
- Full-text search (`@@` operator with `to_tsquery`)  
- Pattern matching (`ILIKE` operator)

### 🧠 Technical Rationale: Why the Wrapper Function?
**The Challenge:**  
PostgreSQL's built-in `unaccent()` is marked as **STABLE**, but
`GENERATED ALWAYS AS` expressions (used for search vector columns)
require **IMMUTABLE** functions.

**The Solution:**  
Created an IMMUTABLE wrapper function that calls the underlying
`unaccent()` function:
-  Satisfies PostgreSQL's immutability requirements for generated
columns
-  Maintains the exact same functionality as the original `unaccent()`
-  Uses fully qualified `public.unaccent_immutable()` to ensure
function resolution from workspace schemas

**Alternative Approaches Considered:**  
-  Modifying `search_path`: would affect workspace isolation  
-  Computing unaccent at query time: would hurt performance  
-  Using triggers: would complicate data consistency

### 🎯 Impact
For **Person** records, accent-insensitive search now works on:  
- Name (first/last name): `"jose garcia"` finds `"José García"`  
- Email: `"jose@cafe.com"` finds `"josé@café.com"`  
- Job Title: `"manager"` finds `"Managér"` or `"Gerente de Café"`

Applies to all searchable standard objects:  
- Companies, People, Opportunities, Notes, Tasks, etc.  
- Any custom fields of searchable types (TEXT, EMAILS, etc.)

###  Testing
- Database reset completes successfully  
- Workspace seeding works without errors  
- Search vectors generate with unaccent functionality  
- All searchable field types properly handle accented characters

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-09-17 09:01:35 +02:00
Abdul Rahman 172cc12a82 feat: Add xAI models support (#14523) 2025-09-16 17:55:11 +02:00
github-actions[bot] 4f63f55686 i18n - translations (#14536)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-16 14:59:42 +02:00
Paul Rastoin 371c26bc9b Flat entity maps cache generic service + runner dynamically retrieving invalidating update cache + view service v2 refactor (#14508)
# Introduction
Migrate previous runner only iterating on `flatObjectMetadataMaps` to
`allFlatEntityMaps`.
Refactored the optimistic to be handled inside the actions handler

## Workspace flat map cache
Introducing a new service and registry, that will dynamically retrieve
and or recompute requested cache when called

## Runner refactor
Runner now dynamically invalidate updated cache at the end of the
transaction

close
https://github.com/orgs/twentyhq/projects/1/views/8?pane=issue&itemId=129136356&issue=twentyhq%7Ccore-team-issues%7C1492
close
https://github.com/orgs/twentyhq/projects/1/views/8?pane=issue&itemId=129136210&issue=twentyhq%7Ccore-team-issues%7C1494
2025-09-16 14:39:42 +02:00
github-actions[bot] c738ba54ad i18n - translations (#14503)
Created by Github action

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-15 15:38:21 +02:00
martmull 57ff06f47c 1487 extensibility look into public domains to identify workspace (#14456)
- identify workspace based on public domains
- add cron job to validate public domains
- add endpoint to validate a public domain
2025-09-15 15:14:11 +02:00
github-actions[bot] c481fda0bd i18n - translations (#14499)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-15 14:43:24 +02:00
Paul Rastoin 579f704baa Plugging + improving the new orchestrator (#14430)
# Introduction
Initially this PR was about introducing integration coverage for view
field v2 tests
But feature itself wasn't finished, so ended up in a TDD style
devlopment

## The new orchestrator
Orchestrator will organize each flat entity diffing inferring either
validation errors or actions sequentially.
A new builder has been introduced when extended requires to define flat
entity validation utils and action generation for `delete` `update`
`create` operations. It's highly typed using generics

## View field integration testing
Introduce coverage on failing basic tests cases for view field
operations, successfull create is also covered. We could still add more
coverage, will be done later in following PRs

## Remaining tasks for upcoming PRs:
- [ ] rename builder methods names to add generate action in their names
- [x] refactor view validation to handle field and view uniqueness index
combination
- [ ] implem strict update validator on view and view field
- [ ] dynamic cache invalidation post run
- [ ] Add coverage to successful and failing view field operations
- [ ] error formatting summary computation
- [ ] extract types out of the workspace entity builder

## Some vision
Currently flat field metadata maps is nested in the flat object metadata
maps, making its build nested too. ( not extending the new generic
builder )
We will refactor this part for both to be stored extra flat such as the
other existing flat entities.
It will require a small refactor to the generic builder that will not
only have impact on the currently built flat entity optimistic cache but
to an other one ( for example when building a create object action it
will also have an impact flat field maps )
2025-09-15 14:32:57 +02:00
Etienne 06605b2f36 simplify gql schema gen (#14426)
closes https://github.com/twentyhq/core-team-issues/issues/1358
2025-09-15 14:01:53 +02:00
Thomas Trompette 155aa4995e Handle edge deletion from loop (#14489)
Update delete edge endpoint. It should handles the deletion between the
iterator and the loop step ids
2025-09-15 10:20:33 +02:00
Weiko eada8e2567 Add calendar field metadata id to view table (#14478) 2025-09-15 09:17:17 +02:00
Charles Bochet e13db84f48 Create empty page for calendar table (#14479)
<img width="1512" height="876" alt="image"
src="https://github.com/user-attachments/assets/e845fb3a-9977-4ab7-9eb7-4e60e499165b"
/>
2025-09-14 18:03:38 +02:00
Weiko f46d67f9f3 Add calendar view type (#14475) 2025-09-14 16:34:10 +02:00
Charles Bochet 1e97ad48c0 Fix on view filters (#14462)
Fixes https://github.com/twentyhq/twenty/issues/14058
2025-09-12 22:45:26 +02:00
Charles Bochet a4cf534130 Fix View picker dropdown placement (#14457)
Fixes https://github.com/twentyhq/twenty/issues/14445

## What

In the current `MenuItemWithOptionDropdown` component (which is a
MenuItem with the 3 dots dropdown), we used to have a position: static
on the 3 dots hovered.
This enabled the dropdown to not move when we scroll the MenuItems.

However, this is not playing well with the dropdown autoplacement.
I'm removing it as I think the right solution would actually to prevent
the scroll when the dropdown is open but this is non straight forward
and not really a big issue. I'm fine with the dropdown being "fixed" to
the scrollable content, it also makes sense

Before:


https://github.com/user-attachments/assets/8efec8fa-430a-408e-b549-fd7433b7a38d

After:


https://github.com/user-attachments/assets/b8ee4375-0944-4008-9ab6-f7f9f1d67e9c



## Testing

I was considering adding a story here but this is hard to test: hover +
scroll behavior are not well supported, I don't think it worth the
investment especially as I think the vision is to block the scroll

This componenent is used in ViewPicker and MultiItemsInput (ex.
PhonesFieldInput). I have check that both were still working well
2025-09-12 19:45:23 +02:00
Marie 89254ea9e9 Limit rest api relations depth to 1 (#14453)
Until we tackle [Implement relations depth 2 for rest
api](https://github.com/twentyhq/twenty/issues/14452), let's remove the
depth 2 query parameter which is not working (times out all the time).
2025-09-12 15:57:16 +00:00
Thomas Trompette 12a5ee6bc4 Add connection options on edge creation (#14451)
Edge can now be linked to loop handle.
Renaming the existing options to connection.
2025-09-12 14:08:20 +00:00
Marie 3270c64a96 [permissions] Deprecate ObjectsPermissionsDeprecated (2/3) (#14450)
Following https://github.com/twentyhq/twenty/pull/14306 , working on the
deprecation of objectRecordsPermissions + renaming of objectPermissions
-> objectsPermissions

In this PR
- Removal of objectRecordsPermissions (was not used in the FE any
longer)
- Addition of objectsPermissions, same as objectPermission but renamed.
objectPermission is no longer used in the FE.

Next step
- Remove unused objectPermissions
2025-09-12 16:02:42 +02:00
nitin 7c26b1cce3 [Dashboards] - Add seeds (#14404)
closes https://github.com/twentyhq/core-team-issues/issues/1440
2025-09-12 14:35:51 +02:00
Thomas Trompette 231d1a98af Allow to insert into loop step ids (#14425)
- Create empty node on iterator creation
- Add options on step creation to insert in loop
- Handle properly when a step is removed from loop
- Remove loopNextStepIds from frontend action
- Add a frontend skeleton for empty action



https://github.com/user-attachments/assets/281a8c15-8062-4702-afb4-0d9a50902252
2025-09-12 07:30:28 +00:00