Commit Graph

1189 Commits

Author SHA1 Message Date
Marie 3dd70aad03 [command fix] Limit migration to workflow versions (#15145)
This migration updates the filter operand values of the workflowVersion
and workflowRuns in order to capitalize them as they should be (the
product works with both deprecated camel case and capitalized). But that
may involve thousands of workflowRuns!
Let's update the command to only update workflowVersion, and update the
cleanWorkflowRuns job to remove workflow runs that are more than 14 days
old.

This way after the command is run, all new workflow runs will have the
new value for the filter operand, and after fourteen days there will be
no trace of the workflow runs with the deprecated filter operand.
2025-10-16 18:03:22 +02:00
Etienne b2247a7a3d Release - Fix migration channel sync stage command (#15141) 2025-10-16 16:06:14 +02:00
Etienne 5cbaa9f4d7 Release - add command in upgrade command (#15134) 2025-10-16 15:17:49 +02:00
Etienne a5790e3967 Release - switch 1.10 to 1.8 (#15124)
Before
<img width="500" height="500" alt="Screenshot 2025-10-16 at 11 38 07"
src="https://github.com/user-attachments/assets/7fb99487-8e18-41e4-b7e1-0951782480c2"
/>
After
<img width="500" height="500" alt="Screenshot 2025-10-16 at 11 37 58"
src="https://github.com/user-attachments/assets/602c188b-0208-4e74-a3b6-5631df1bb968"
/>
2025-10-16 09:48:30 +00:00
Abdullah. d750df7fff Automatically clean up soft-deleted records after X days. (#14862)
Closes #14726

### Added
- `trashRetentionDays` field to workspace entity (default: 14 days)  
- Automated trash cleanup using BullMQ jobs  
- Daily cron (00:10 UTC) that enqueues cleanup jobs for all active
workspaces
- Per-workspace limit: 100k records deleted per day  
- Calendar-based retention: records deleted on day X are cleaned up X+14
days later (at midnight UTC boundaries)

### Architecture
- **Cron (WorkspaceTrashCleanupCronJob):** Runs daily, enqueues jobs in
parallel for all workspaces
- **Job (WorkspaceTrashCleanupJob):** Processes individual workspace
cleanup
- **Service (WorkspaceTrashCleanupService):** Discovers tables with
`deletedAt`, deletes old records with quota enforcement
- **Command:** `npx nx run twenty-server:command
cron:workspace:cleanup-trash` to register the cron

### Testing
- Unit tests for service with 100% coverage of public API  
- Tested quota enforcement, error handling, and edge cases

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-14 18:49:40 +02:00
Abdullah. d6526af302 Move search vector command from 1-7 to 1-10 and make it less verbose. (#14892)
Made the command more explicit for idempotency.

- Drop index explicitly (even though PostgreSQL does it automatically
when a column is dropped, but it might be good practice to account for
any unforeseen failures).
- Drop column.
- Create column.
- Create index (if we reach this point, column has already been created
and no error was thrown).
 
Figured we do not need extra queries to check ObjectMetadata for the
existence of person table on a workspace - we can use the IF EXISTS
syntax instead.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-10-12 18:25:45 +02:00
neo773 6f49fd1911 Message channel change 1 (#14942) 2025-10-11 18:18:44 +02:00
Etienne 560e24fa4b Update unique fields on standard field - include soft deleted records (#14562)
Done : 
- migrate standard unique fields (add : -old)
- deactivate defaultWhereClause
- restore soft deleted if upserted (same for contact creation in mailing
sync)

fixes https://github.com/twentyhq/twenty/issues/14443

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-11 15:50:29 +02:00
Paul Rastoin 59fbe35a8c Move view in metadata-modules/ and create atomic folder + module for each view entity (#14990)
# Introduction
Preparing view-filter and view-group introduction in v2 core engine
Moving view from `core-modules` to `metadata-modules`

## What happened

### Created dedicated modules for each view entity:
- ViewFieldModule
- ViewFilterModule
- ViewFilterGroupModule
- ViewGroupModule
- ViewSortModule

### Each module is now completely independent with its own:
- Controller
- Resolver
- Service
- Entity

### Created dedicated abstraction metadata module folder for:
- flat-view-field
- flat-view

### Dependencies 
- Eleminated circular dep on ViewModule to all others ones
- Granular import not importing the whole viewModule anymore everywhere


close https://github.com/twentyhq/core-team-issues/issues/1703
2025-10-09 15:18:15 +02:00
martmull 5252384f14 1588 serverless follow ups 2 (#14998) 2025-10-09 12:56:59 +02:00
Marie ebc6bbabaf [Fix] Command to migrate operand values for workflows (#14849)
In [this PR](https://github.com/twentyhq/twenty/pull/14785) we got rid
of what we now call ViewFilterOperandDeprecated, a camelCase version of
ViewFilterOperand, which we thought we only used in the FE. We did not
notice that this enum was used to persist filters used in workflows,
reflected in workflowVersion and workflowRun.
As a result workflow runs were broken. [In this mitigation
PR](https://github.com/twentyhq/twenty/pull/14837) (and [this
one](https://github.com/twentyhq/twenty/pull/14841)) we updated the code
handle both enum values from ViewFilterOperandDeprecated and
ViewFilterOperand, but we still want to get rid of
ViewFilterOperandDeprecated.

the command in this PR replaces the occurences of enum values of
ViewFilterOperandDeprecated.
When this has been merged, deployed and run on the workspaces, we will
be able to remove ViewFilterOperandDeprecated altogether; that will have
to be done in 1.10 though not before.
2025-10-09 09:45:44 +00:00
Abdul Rahman 0648dc5c65 Fix AI chat streaming persistence when command menu closes (#14854)
Closes [#1583](https://github.com/twentyhq/core-team-issues/issues/1583)


- Removed `messageId` column from `File` table and its references in
code (unrelated to this PR)
- Updated AI chat to use React Context API with persistent provider in
`CommandMenuContainer`
- Converted all AI chat component states to regular Recoil atoms (no
instance context needed)

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-10-03 12:37:41 +02:00
Weiko 0b60aa4249 Add custom routes to migration v2 (#14846)
## Context
Add routes to migration V2
- Resolvers
- Service v2
- Builder
- Validator
- Action runner

Next PR: Add to twenty-cli to sync routes with serverless
2025-10-03 00:20:21 +02:00
martmull 87256e82f5 Improve readme (#14858) 2025-10-02 22:50:37 +02:00
Marie aac1314f5b [Fix] Handle deprecated viewFilterOperand in workflows run & on interface (#14837)
In this PR https://github.com/twentyhq/twenty/pull/14785 we deprecated
viewFilterOperand (from camelCase to capital snakeCase values), but we
had not migrated the existing workflow steps values. Hence they cannot
be executed!

Let's fix that by dealing with both operands, new and deprecated, to
mitigate the issue. Then we will add a command to migrate the values.
2025-10-02 13:08:24 +02:00
Weiko 64dc726f50 rename application standardId to universalIdentifier (#14825)
## Context
Rename standardId in application table to universalIdentifier to align
with the rest of migration v2 guidelines
2025-10-01 20:20:20 +02:00
Charles Bochet ec317bd3d0 Fix workflow upgrade command (#14824)
While upgrading to 1.7.0, we are facing an error in the workflow version
upgrade for outdated workflow versions. Fixing the command
2025-10-01 19:57:43 +02:00
Abdul Rahman 20403664e3 Feat: native model capabilities (#14787) 2025-10-01 18:37:21 +02:00
martmull 1938202780 1573 extensibility twenty cli handle custom layers for serverless functions of applications (#14779)
- allow specific layers for serverless functions
- add a serverlessFunctionLayer table
- sync application layer
2025-09-30 16:47:49 +02:00
Thomas Trompette b7cdf9183a Search record action - allow to search more than 1 record (#14769)
https://github.com/user-attachments/assets/426da6af-6c6b-4d49-9034-0aa041cb331f
2025-09-30 12:07:25 +02:00
Weiko 68b21d2942 Add db event trigger and cron trigger to migration v2 (#14772)
## Context
Add DB events triggers and Cron triggers to migration v2 builder/runner
(and adding corresponding services/resolvers)
2025-09-30 11:14:18 +02:00
Antoine Moreaux 7692fb2b6c chore(billing): add tests + fix meter name for trial (#14701)
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Righteousness Akinbola <righteousnessakinbola@gmail.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: martmull <martmull@hotmail.fr>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
Co-authored-by: Abdullah. <125115953+mabdullahabaid@users.noreply.github.com>
Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
2025-09-30 10:01:51 +02:00
Thomas Trompette 4329501743 Workflow run over a list of records + backfill availability on manual triggers (#14761)
- Allow to run workflow on a list of records
- Use new availability in manual trigger when iterator feature flag is
enabled
- Build a command to backfill availability in workflow trigger



https://github.com/user-attachments/assets/d685c01f-4059-4647-92a1-f5f529b560cf
2025-09-29 13:45:51 +00:00
Abdul Rahman 2685f4a5b9 Restructure agent chat messages with parts-based architecture (#14749)
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-29 13:31:55 +02:00
Weiko 584389e17f add code checksum to flat serverless function (#14721)
## Context
Now adding serverless code sync within the migration v2 logic itself. To
do that we need to follow the
- Prepare flat input
- Build migration
- Run migration
steps where now the serverless function entity will store in DB and
cache a checksum of its code and the flat input will contain the code
with the checksum. Build will compare checksum and create an update
action containing the code if it has changed and the migration will now
run the corresponding services (instead of calling those in the parent
serverless service exposed in the API) allowing us to keep that logic
functional for other use cases such as import/export, twenty-cli and
twenty upgrades.
2025-09-26 10:24:36 +02:00
Abdullah. 5a56d73fb2 Enables phone number search in the global search (Command Menu) for person records. (#14636)
## Changes Made

- Added phone fields to search indexing: Extended searchable field types
to include `FieldMetadataType.PHONES`
- Updated person entity search configuration: Added `phones` to the
fields indexed for person records
- Enhanced search format support: Phone numbers are now indexed in
multiple formats:
  - Raw number: `2071234567`
  - International with plus: `+442071234567`
  - International without plus: `442071234567`
- Optimized for phone data: Removed unnecessary text processing (e.g.
unaccenting) for numeric phone fields
- Created workspace migration: New command to regenerate search vectors
for existing workspaces

## Technical Details

The implementation modifies PostgreSQL `tsvector` generation to index
both `primaryPhoneNumber` and `primaryPhoneCallingCode` fields,
combining them into international formats. This enables users to search
phone numbers using the formats they naturally type.

### Modified Files

- `is-searchable-field.util.ts` – Added `PHONES` to searchable types
- `person.workspace-entity.ts` – Included `phones` in person search
fields
- `get-ts-vector-column-expression.util.ts` – Enhanced expression
generation to support multiple phone number formats
- `is-searchable-subfield.util.ts` – Added subfield filtering logic for
phone fields

## Testing

- **Unit tests**: Validated `tsvector` expression generation and
phone-specific logic
- **Integration tests**: Covered phone search scenarios across multiple
formats

## Migration

Includes the `upgrade:1-7:regenerate-person-search-vector-with-phones`
command, which safely updates existing workspaces by dropping and
recreating search vectors with phone indexing support.

## Note

Frontend and Backend are both storing normalized phone numbers, as they
should. The issue turned out to be with the seed file instead, which
contained outdated records.

I relied on the database as the source of truth without testing via the
creation of a new record and it was an incorrect evaluation on my part.
Note taken, I will be more comprehensive with my analysis from here on
since I now understand I must check comprehensively before reaching a
conclusion.
2025-09-25 20:18:49 +02:00
Weiko 188d66909d Add ServerlessFunction to migration v2 (#14698) 2025-09-25 14:05:01 +02:00
martmull edb331d68b 1541 extensibility twenty cli use workspace migration v2 to synchronize application objects fields views (#14706)
- synchronize objects


https://github.com/user-attachments/assets/257317bc-2881-4b98-a3d4-6ae52bd72aa0
2025-09-25 11:22:11 +02:00
neo773 a1ad8e3a1e Outbound message domains (#14557)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-24 10:33:04 +02:00
Antoine Moreaux a89e5d0f27 feat(database): activate unaccent extension with immutable function (#14621) 2025-09-21 15:17:19 +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
Paul Rastoin 39661db3c8 Setup 1.6 commands (#14614) 2025-09-19 12:32:13 +00: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
Félix Malfait fda3183ba6 Add missing migration for unaccent (#14566)
It was in setup-db.ts but that's not enough for instances that are
already live

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-09-17 17:13:49 +02:00
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
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 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
Weiko eada8e2567 Add calendar field metadata id to view table (#14478) 2025-09-15 09:17:17 +02:00
Weiko f46d67f9f3 Add calendar view type (#14475) 2025-09-14 16:34:10 +02:00
martmull b84f4075e5 14240 extensibility ability to create multiple custom domains for each workspace 2 (#14307)
Adds a public-domain core-module. 
Reorganize custom-domain files properly
2025-09-11 12:24:57 +02:00
Félix Malfait 30a2164980 First Application POC (#14382)
Quick proof of concept for twenty-apps + twenty-cli, with local
development / hot reload

Let's discuss it!



https://github.com/user-attachments/assets/c6789936-cd5f-4110-a265-863a6ac1af2d
2025-09-10 15:12:38 +02:00
Charles Bochet 9a05daa624 Fix view advanced filters broken (#14387)
## Context

We recently migrated from workspaceSchema.views to core.views. While
doing it we've migrated views using 1-5-migrate-views-to-core command
but we forgot to migrate the subFieldName

Closes: https://github.com/twentyhq/twenty/issues/14369
2025-09-10 13:59:34 +02:00
nitin 4ba1bd24f0 remove IS_API_KEY_ROLES_ENABLED feature flag (#14366) 2025-09-09 19:29:29 +02:00
Paul Rastoin 9e81618773 Refactor morph field name and morph data loader (#14299)
# Introduction
Storing morph relation field names directly in database, using morphId
to aggregate them
Removing dynamic morph field metadata computation in schemas and data
loader

Will add integration tests on morph data loader entry

closes https://github.com/twentyhq/core-team-issues/issues/1425 
closes https://github.com/twentyhq/core-team-issues/issues/1424 
closes https://github.com/twentyhq/core-team-issues/issues/1423
2025-09-08 17:20:18 +02:00
Charles Bochet a758154690 Add clean workspace cron command (#14353) 2025-09-08 16:46:31 +02:00
Charles Bochet f802294c84 Improve upgrade command and prepare 1.5 release (#14325)
In this PR:
- refactor the upgrade command / upgrade command runner to keep upgrade
command as light as possible (all wrapping logic should go to upgrade
command runner)
- prevent any upgrade if there is at least one workspace.version <
previsousVersion ==> this leads to corrupted state where only core
migrations are run if the self-hoster is skipping a version
2025-09-05 15:58:17 +02:00
Vinay Arvind Badgujar 5824637d1a fix - newly added object not visible in left menu (#14202)
resolves #14190 

added refreshCoreViews() call after object creation to immediately
update core views state, ensuring new objects appear in the navigation
drawer without requiring a refresh

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
Co-authored-by: prastoin <paul@twenty.com>
2025-09-05 10:43:03 +02:00
Raphaël Bosi 9746c3a787 Create PageLayoutTab resolver and controller (#14284)
Closes https://github.com/twentyhq/core-team-issues/issues/1394
2025-09-04 16:07:33 +00:00
Abdul Rahman 79bcd90d8d Feat: role applicability controls (#14239)
Closes [#1404](https://github.com/twentyhq/core-team-issues/issues/1404)

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2025-09-04 08:58:50 +05:30