Commit Graph
3137 Commits
Author SHA1 Message Date
EtienneandGitHub 674ddbd525 Fix raw json validation (#15931)
Before validation in common layer, stringified json were accepted in raw
json field. Fix regression

related to
https://discord.com/channels/1130383047699738754/1130383048173682821/1440723288090218636
2025-11-19 19:05:02 +01:00
Aman RajandGitHub 0223851620 Fixed eslint warnings on changed files (#15928) 2025-11-19 17:13:07 +01:00
neo773andGitHub 67846c05bf revert PR 12884 (#15922)
this PR never really addressed the root cause which was later addressed
in the auth refactor PR so reverting this as it's also causing some
errors.
2025-11-19 14:28:00 +01:00
Félix MalfaitandGitHub bf638c3a4e Fix file controller route parameter extraction (#15924)
## Problem
When accessing file URLs like `/files/attachment/{token}/{filename}`,
the server was returning 500 errors with no logs. The issue was that the
route pattern `*path/:filename` was not properly extracting parameters,
causing `request.params[0]` to be undefined.

## Solution
- Changed route from `@Get('*path/:filename')` to
`@Get(':folder/:token/:filename')` for explicit parameter extraction
- Simplified `extractFileInfoFromRequest` to use named route parameters
directly instead of complex path parsing
- Removed unnecessary logging that was added during debugging
- Added test to verify route parameters are correctly extracted and
passed to FileService

## Testing
- Added unit test that verifies folder, token, and filename parameters
are correctly passed to the service
- Test will catch any future regressions where route parameters are not
properly extracted
2025-11-19 14:12:34 +01:00
6fa75e1360 i18n - translations (#15908)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-18 18:01:56 +01:00
Abdullah.andGitHub 9c61b625a1 Remove the redundant nx/js package from twenty-server since root has it. (#15905)
There was an extra definition of @nx/js inside twenty-server, which was
not recognized during upgrade by the CLI. This caused two versions of
@nx/js in the repo - 22.0.3 from root and 21.3.11 from the twenty-server
package.

Removed the one inside twenty-server to maintain a single source of
truth.
2025-11-18 17:41:45 +01:00
MarieandGitHub 5bb4abc23d Add optional limit variable to groupBy queries (#15885)
Closes https://github.com/twentyhq/core-team-issues/issues/1600.

Two remarks 
- This `limit` variable does not reduce postgre's work at it still needs
to scan the whole table. It did not seem possible to me to optimize this
as we cannot foresee which dimensions will be used by the user, and an
optimization could only result from an index on the dimension(s) (e.g.:
group companies by addressCity limit 50 can be optimized if we have an
index on companies.addressCity + we had a default orderBy on
adressCity). But this will still optimize the FE which at the moment
receives all groups and truncates the result.
- I have not done the work on the FE as the addition of limit is a
breaking change, and will break until the workspaces' schema is rebuilt,
so we need to flush the cache. I think this could be acceptable as the
feature is in the lab but I preferred not doing it yet as it would have
no impact since in the BE I added a default limit to 50 groups, and I
expect more FE work will be done to allow the user to choose their own
limit
2025-11-18 17:25:33 +01:00
e02c24bd3a i18n - docs translations (#15904)
Created by Github action

---------

Co-authored-by: Abdul Rahman <ar5438376@gmail.com>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-18 17:21:48 +01:00
neo773andGitHub 46149cdb14 add case for calendar revoked refresh token (#15837) 2025-11-18 17:14:31 +01:00
Abdullah.andGitHub 222feb90b4 fix: update glob version to 11.1.0 (#15884)
Some Glob CLI related alerts were generated last night. I believe
they're safe to dismiss since I do not expect us to use the Glob CLI in
production environment, and those alerts do not impact the API, but
still updating the dependency version just in case.

Not sure if this would resolve all/any of the alerts since glob is a
dependency for many other dependencies, so a good number of dependency
variants are pulled in.

The alert that confirms it's just a CLI related vulnerability:
[Dependabot Alert
307](https://github.com/twentyhq/twenty/security/dependabot/307)
2025-11-18 17:12:53 +01:00
neo773andGitHub cbb5bce500 expose imap username field (#15866)
Had an edge with a customer where they had a custom username.
2025-11-18 17:12:02 +01:00
neo773andGitHub 347e855b1f update default message folder import policy to ALL_FOLDERS (#15858) 2025-11-18 16:59:15 +01:00
EtienneandGitHub db48059bea Fix test (#15895) 2025-11-18 16:55:54 +01:00
martmullandGitHub f131a86cc5 Update lock parameters (#15901)
as title
2025-11-18 15:40:42 +00:00
martmullandGitHub ee648197df Set TTL >> max await + increase max await from 1s to 2s (#15892)
- set TTL >> max await
- increase max await from 1s to 2s
2025-11-18 16:25:04 +01:00
martmullandGitHub bbe104c27b Fix asset path (#15888)
As title
Fix workflow code step creation error
2025-11-18 13:55:34 +01:00
nitinandGitHub 8434610f18 seperate v1 and v2 seeds, make groupMode to add default in case its not provided through api but primary groupBy is present (#15815)
Context - 
- refactoring v1 and v2 seeds to test v2 dashboard flag both on and off
Right now, the db reset command fails if the feature flag is off

- whenever there is a groupBy field -- we should add a default groupMode
- we already do that on the front -- but implementing the same on server
so that api users get the same response

This is also the reason why the second seed on dashboards lags a lot --
because on that particular dashboard's widget -- we set groupBy but no
groupMode (in seeding util) -- and the effect of limiting the bars to
fifty runs depending on the groupMode
2025-11-18 11:29:12 +00:00
76cc07a5f7 Revert x2 - Common - Field validation (#15491) (#15879)
Revert https://github.com/twentyhq/twenty/pull/15821

Should not have been reverted. Conflicting with this
[PR](https://github.com/twentyhq/twenty/pull/15742),
[reverted](https://github.com/twentyhq/twenty/pull/15875)

Co-authored-by: Weiko <corentin@twenty.com>
2025-11-18 12:04:00 +01:00
martmullandGitHub d0d90735cb Revert "refactor: Simplify CRUD services to leverage Common API (#157… (#15875)
This reverts commit 11e07f90d2.
2025-11-18 09:44:15 +01:00
Félix MalfaitandGitHub 0fa2a4524a feat: Add filter button to objects table and enable system objects access (#15856)
## Summary
This PR replaces the Active/Inactive accordion sections with a modern
filter dropdown button and enables full access to system objects in
advanced mode.

## Changes

### UI Improvements
-  Replaced accordion sections with a filter button dropdown (matching
the design pattern from the Group filter)
-  Added 'Deactivated' toggle filter (hidden by default, uses
IconArchive)
-  Added 'System objects' toggle filter (only visible in advanced mode,
uses IconSettings)
-  Fixed search input width to properly fill available space
-  Proper button sizing and alignment

### System Objects Support
-  Made system objects visible when 'System objects' filter is toggled
on
-  System objects are now fully clickable and accessible
-  Updated object detail page to support system objects
-  Updated field creation/edit pages to support system objects
-  System objects can now have custom fields added

### Architecture
-  Implemented scalable filter architecture using a single filtered
list
-  Easy to add more filters in the future (e.g., show remote objects)
-  All filters work independently and can be combined

## Testing
- [x] Tested deactivated objects toggle
- [x] Tested system objects toggle (only shows in advanced mode)
- [x] Tested clicking on system objects
- [x] Tested adding custom fields to system objects
- [x] No linter errors

## Screenshots
See attached screenshots in the conversation for the new filter UI.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds a filter dropdown to the Settings Objects table (incl.
deactivated/system toggles), enables system objects across
settings/field flows, seeds core views (workspace members, messages,
threads, calendar events), and adds actions for Workspace Members.
> 
> - **Settings UI**
> - **Objects Table**: Replaces Active/Inactive sections with a single
filterable list and dropdown (`Deactivated`, `System objects` in
advanced mode); updates props to `objectMetadataItems` and removes
accordion sections.
> - **Search/UX**: Search input fills available space; inactive rows
show activation/delete menu; active rows remain navigable.
> - **Pages Updated**: `SettingsObjects`,
`SettingsApplicationDetailContentTab` switch to new table API; object
detail and new-field flows use `findObjectMetadataItemByNamePlural`
(works with system objects).
> - **Action Menu**
> - **Workspace Members**: Adds `WORKSPACE_MEMBERS_ACTIONS_CONFIG` with
"Manage members in settings" action; wired into `getActionConfig` for
`WorkspaceMember`.
> - **Server (Core Views Seed)**
> - Adds default views: `workspaceMembersAllView`, `messagesAllView`,
`messageThreadsAllView`, `calendarEventsAllView`; included in
`prefillCoreViews`.
> - Marks workflow entities as system (`WorkflowRun`,
`WorkflowVersion`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6a2856df85. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-17 19:10:19 +01:00
Abdullah.andGitHub 60ed9b53f4 fix: vercel’s AI SDK's filetype whitelists can be bypassed when uploading files (#15874)
Resolves [Dependabot Alert
301](https://github.com/twentyhq/twenty/security/dependabot/301).

Locked the version of "ai" at 5.0.52 in order to stop it from bumping to
5.0.93 directly when the ^ is introduced since it breaks the code across
multiple files.
2025-11-17 18:03:45 +00:00
Félix MalfaitandGitHub 19ca93b954 Fix auth connection (#15869)
Better to do auth this way than in module
2025-11-17 18:12:48 +01:00
Paul RastoinandGitHub a39efeb1ab [BREAKING_CHANGE/GRAPHQL/OBJECT_METADATA_CREATE_ONE] Remove object/fields/view-fields v1 implementation (#15823)
# Introduction
Remove the v2 feature flag for view-field field-metadata and
object-metadata metadata entities

## Some details
- Disabled nestjs-query for object metadata creation and explicitly
calling it
- removed all v1 integration tests files

## Remarks
Not remove v2 referencing in both filenaming right now will handle that
globally later

## Breaking change
Due to object metadata resolver createOne standardization had to rename
the input from `CreateObjectInput` to `CreateOneObjectInput`
2025-11-17 10:55:19 +01:00
Paul RastoinandGitHub 48031a7ce2 Runner v2 on cascade delete_field/object + refactor workspace deletion side effect (#15830)
# Introduction
While removing the v1 https://github.com/twentyhq/twenty/pull/15823 I've
encountered the method `objectMetadataService.deleteObjectsMetadata`
that I didn't wanted to migrate as it is and if it's not challenging its
existence legitimacy.

## Motivations
In a nutshell on a workspace deletion object metadata and field metadata
cascading deletion is correclty handled
But that's not the case for all of a workspaces entities ( roles,
workspaceMigrations ) I suspect that we did not defined the foreignKey
explicitly through `typeorm`

## Battle testing v2
I still decided to give a try to a complex operation in the v2 such as a
workspace all object metadata deletion.
Spoiler it failed due to object being interdependent between them and
not being topologically sorted ( morph relation can introduce circular
dep anw ).
Note: Even after removing the delete field on delete object aggregator
we end up with an equivalent circular dep error which an object and its
field metadata identifier connection.

## Elegant `DEFERRED` and `DEFERRABLE` foreign keys
The most safe, low level solution would be to make all field relations
deferrable and start the runner transaction as deferred. But this
requires a quite invasive migration of existing FK

## On cascade solution
I've opted for the quick fix, on object or field deletion spread
cacasde.
It's pretty safe as the builder priorly validates the deletion and and
its related entities integrity
Only for both field and object deletion action types in v2 runner

## Integration coverage
Added a test that will scan a new workspace database core schema tables
and expect now result after workspace deletion through its only user
deletion
2025-11-16 22:03:50 +01:00
Félix MalfaitandGitHub 5dfb66917c Upgrade NestJS from 10.x to 11.x (#15836)
## Overview
This PR upgrades all NestJS dependencies from version 10.x to 11.x,
following the [official migration
guide](https://docs.nestjs.com/migration-guide). This builds on top of
the v9 to v10 upgrade completed in PR #15835.

## Changes

### Dependencies Updated
**Core packages (10.x → 11.x):**
- `@nestjs/common`: 10.4.16 → 11.0.8
- `@nestjs/core`: 10.4.16 → 11.0.8
- `@nestjs/platform-express`: 10.4.16 → 11.0.8
- `@nestjs/config`: 3.2.3 → 3.3.0
- `@nestjs/passport`: 10.0.3 → 11.0.0
- `@nestjs/axios`: 3.0.2 → 3.1.2
- `@nestjs/schedule`: ^3.0.0 → ^4.1.1
- `@nestjs/serve-static`: 4.0.2 → 5.0.1
- `@nestjs/cache-manager`: ^2.2.1 → ^2.3.0
- `@nestjs/jwt`: 10.2.0 → 11.0.0
- `@nestjs/typeorm`: 10.0.2 → 11.0.0
- `@nestjs/terminus`: 11.0.0 (already on v11)
- `@nestjs/event-emitter`: 2.1.0 (compatible)

**DevDependencies:**
- `@nestjs/testing`: ^10.4.16 → ^11.0.8
- `@nestjs/schematics`: ^10.1.0 → ^11.0.2
- `@nestjs/cli`: 10.3.0 → 11.0.0

### Code Changes
**Fixed: TwentyConfigModule conditional imports**
- Updated `TwentyConfigModule.forRoot()` to use spread operator for
conditional imports
- Fixes TypeScript error with NestJS 11's stricter DynamicModule type
checking

**Cleanup: Removed unused package**
- Removed `@revertdotdev/revert-react` (not being used anywhere in the
codebase)

## Breaking Changes Addressed

### 1.  Reflector Type Inference
- **Impact**: None - codebase only uses `reflector.get()` method
- **Analysis**: Does not use `getAllAndMerge()` or `getAllAndOverride()`
(the methods with breaking changes)
- **Files reviewed**: feature-flag.guard.ts,
message-queue-metadata.accessor.ts,
workspace-query-hook-metadata.accessor.ts

### 2.  Lifecycle Hooks Execution Order
- **Change**: Termination hooks (`OnModuleDestroy`,
`BeforeApplicationShutdown`, `OnApplicationShutdown`) now execute in
REVERSE order
- **Analysis**: Reviewed all lifecycle hook implementations
  - Redis client cleanup
  - Database connection cleanup (GlobalWorkspaceDataSource)
  - BullMQ queue/worker cleanup
  - Cache storage cleanup
- **Result**: Dependency order is safe - services using connections
clean up before the connections themselves

### 3.  Middleware Registration Order
- **Change**: Global middleware now executes first regardless of import
order
- **Analysis**: Middleware is not registered as global, so execution
order remains consistent
- **Files reviewed**: app.module.ts, middleware.module.ts

## Testing

All tests passing and build successful:

**Unit Tests (283+ tests):**
-  Health module: 38 tests passed
-  Auth module: 115 tests passed (passport v11 integration)
-  REST API: 90 tests passed (middleware and express platform)
-  Feature flags: 17 tests passed (Reflector usage)
-  Workspace: 23 tests passed

**Build & Quality:**
-  Type checking: Passed
-  Linting: Passed
-  Build: 3,683 files compiled successfully

## Verification

Tested critical NestJS functionality:
-  Authentication & Security (JWT, OAuth, guards)
-  HTTP Platform (Express integration, REST endpoints)
-  Dependency Injection (Services, factories, providers)
-  Cache Management (Redis with @nestjs/cache-manager)
-  GraphQL (Query runners, resolvers)
-  Configuration (Environment config)
-  Scheduling (Cron jobs with @nestjs/schedule v4)
-  Lifecycle Hooks (Module initialization and cleanup)
-  Reflector (Metadata reflection in guards)

## Related PRs
- #15835 - Upgrade NestJS from 9.x to 10.x (completed)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Upgrades NestJS to v11 and updates routing patterns, auth strategies,
GraphQL schema options, and build/dist paths (scripts, Docker, Nx,
migrations, assets), plus enables Devtools in development.
> 
> - **Backend (NestJS 11 upgrade)**:
> - Bump `@nestjs/*` packages (core, platform-express, jwt, passport,
typeorm, serve-static, schedule, cli/testing/schematics) to v11.
> - Update REST/route-trigger/file controllers to new wildcard syntax
(`*path`).
> - Refactor OAuth (Google/Microsoft) and SAML strategies (abstract base
+ explicit `validate`); minor typings.
>   - Enable `DevtoolsModule` in development.
> - **GraphQL**:
> - Add `buildSchemaOptions.orphanedTypes` for client-config types; keep
Yoga/Sentry setup.
> - **Build/Runtime & Config**:
> - Standardize dist layout (remove `src` in paths): update scripts,
Docker `CMD`, Nx `project.json`, render scripts, TypeORM migration
paths, asset resolution.
> - Adjust `nest-cli.json` (watchOptions, asset globs, migrations
outDir, monorepo/root).
> - Improve config module imports (spread conditional); tsconfig
excludes `node_modules`.
>   - Minor Nx default: `start` target caching disabled.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1139fd85a9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-16 18:20:06 +01:00
Félix MalfaitandGitHub a2a7ff8b4b Upgrade NestJS from 9.x to 10.x (#15835)
## Overview
This PR upgrades all NestJS dependencies from version 9.x to 10.x,
following the [official migration
guide](https://docs.nestjs.com/v10/migration-guide). This is the first
step before upgrading to NestJS 11.x in a future PR.

## Changes

### Dependencies Updated
- `@nestjs/common`: 9.4.3 → 10.4.16
- `@nestjs/core`: 9.4.3 → 10.4.16
- `@nestjs/passport`: 9.0.3 → 10.0.3
- `@nestjs/platform-express`: 9.4.3 → 10.4.16
- `@nestjs/config`: 2.3.4 → 3.2.3
- `@nestjs/event-emitter`: 2.0.4 → 2.1.0
- `@nestjs/testing`: ^9.0.0 → ^10.4.16
- `@nestjs/schematics`: ^9.0.0 → ^10.1.0

### Code Changes
- Fixed `CacheModuleOptions` import from `@nestjs/common` to
`@nestjs/cache-manager` in cache-storage.module-factory.ts

## Breaking Changes Addressed
 **CacheModule Migration**: Already using `@nestjs/cache-manager`
package
 **TypeScript Version**: Using 5.9.2 (requires 4.8+)  
 **Node.js Version**: Using 24.5.0 (requires 16+)  
 **Deprecated APIs**: All v9 deprecations removed in v10 - standard
patterns in use

## Testing
All tests passing and build successful:
-  Health module: 38 tests passed
-  Auth module: 115 tests passed (critical - uses @nestjs/passport)
-  Admin panel: 30 tests passed
-  REST API: 90 tests passed (uses @nestjs/platform-express)
-  Feature flags: 17 tests passed
-  Workspace: 23 tests passed
-  GraphQL query runner: 17 tests passed
-  **Total: 330+ tests passing**
-  Build: 3,683 files compiled successfully
-  Type checking: Passed
-  Linting: Passed

## Verification
Tested critical NestJS functionality:
- Authentication & Security (JWT, OAuth, guards)
- HTTP Platform (Express integration, REST endpoints)
- Dependency Injection (Services, factories, providers)
- Cache Management (Redis with @nestjs/cache-manager)
- GraphQL (Query runners, resolvers)
- Configuration (Environment config)
- Event Emitters (Event-driven architecture)

## Next Steps
This upgrade positions the codebase for the next upgrade to NestJS 11.x,
which will be handled in a separate PR.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Upgrades NestJS to v10, fixes cache module import, and narrows CI
GraphQL generation diff to generated directories.
> 
> - **Backend**
> - **Dependencies**: Upgrade `@nestjs/common`, `@nestjs/core`,
`@nestjs/platform-express`, `@nestjs/passport`, `@nestjs/config`,
`@nestjs/event-emitter`, `@nestjs/testing`, and `@nestjs/schematics` to
v10-compatible versions in `packages/twenty-server/package.json`.
> - **Code**: Update `CacheModuleOptions` import to
`@nestjs/cache-manager` in
`src/engine/core-modules/cache-storage/cache-storage.module-factory.ts`.
> - **CI**
> - **GraphQL**: Restrict schema change detection to
`packages/twenty-front/src/generated` and
`packages/twenty-front/src/generated-metadata` in
`.github/workflows/ci-server.yaml`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f621230fcf. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-11-15 23:06:13 +01:00
martmullandGitHub f13c36234f Fix workspace-member-id missing from database events (#15819)
As title
2025-11-14 14:03:49 +00:00
martmullandGitHub 867422627c Revert "Common - Field validation (#15491)" (#15821)
This reverts commit 261cba40ef.
2025-11-14 13:47:22 +01:00
martmullandGitHub df58f4102e Fix typo in command (#15818)
as title
2025-11-14 10:42:26 +00:00
WeikoandGitHub 4dd6edb35a Fix authContext missing in ALS WorkspaceContext for global datasource (#15810)
Fixes https://github.com/twentyhq/twenty/issues/15809

## Context
We recently introduced a global datasource now consuming workspace
context from ALS store however the authContext was missing (only the
workspaceId was there) which "broke" event emission, now missing the
workspaceMemberId

This PR adds the missing authContext so we can access from anywhere in
the datasource. We are still passing it as a parameters on repository
level for legacy but in theory we should be able to remove it from
everywhere and consume the context

<img width="929" height="253" alt="Screenshot 2025-11-13 at 18 58 16"
src="https://github.com/user-attachments/assets/3e04f264-95e6-4831-94f3-fc01603f19bd"
/>
2025-11-14 10:59:15 +01:00
WeikoandGitHub 998365457e Improve infer deletion from entities (#15807)
## Context
inferDeletionFromEntities only accepts a set of keys for each entities
that needs deletion. This could be error-prone if tmr we want to add a
new side effect and forget to add the entity when in practice you want
to delete all entities that are in the fromToAllFlatEntityMaps (this is
the case for applications for example)
2025-11-13 18:18:27 +01:00
Raphaël BosiandGitHub 56b3a0e8a5 Fix REST API Delete and Destroy (#15806)
Fixes https://github.com/twentyhq/twenty/issues/15801
2025-11-13 18:14:32 +01:00
9bc5486d0d i18n - translations (#15803)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-13 17:12:39 +01:00
Paul RastoinandGitHub 0fdc7ba834 Twenty-shared tests parses decorator (#15765)
## Introduction
Since we've moved some class validator instances from twenty-server to
twenty-shared tests are red because they do not know how to parse
decorators declarations

We've fixed this by explicitly installing `class-validator` in
`twenty-shared` and configuring jest swc accordingly

## Twenty-server class validator patch
I don't even know if that's something we need anymore
Seems to be a patch either fixing or introducing credit card and phone
number validation
Would prefer discussing the need or not to either before merging this as
it could introduce regression at runtime:
- Centralize the patch to be consumed in both `twenty-server` and
`twenty-shared`
- Remove the patch

We should also document every patch motivations we do as it's quite
though to iterate over a such huge one
2025-11-13 16:06:04 +00:00
8cadd00d34 i18n - translations (#15799)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-13 16:34:00 +01:00
Félix MalfaitandGitHub cd5d0f9eac Introduce agent hints to reduce context bloat (#15763)
Introducing a new pattern that should reduce token consumption by 90%
for the most common use-cases
2025-11-13 16:15:01 +01:00
261cba40ef Common - Field validation (#15491)
Closes : https://github.com/twentyhq/core-team-issues/issues/1622

To do in other PR : 
- Add migration command for non nullable text, raw_json & array fields
- Add null transformation

---------

Co-authored-by: Weiko <corentin@twenty.com>
2025-11-13 15:45:35 +01:00
Félix MalfaitandGitHub f6ed1e8295 Merge data navigator and manipulator agents (#15761)
Merge data manipulator and navigator agents
2025-11-13 15:25:52 +01:00
Charles BochetandGitHub 9bbe0e7f8e Add message folders control in seed by default (#15789)
As per title
2025-11-13 15:09:13 +01:00
0cab2b49fc (breaking change) Allow users with a single workspace to update their email. (#15736)
- Users with a single workspace are allowed to update their email across
`core.user` and `workspace_xyz.workspaceMember`.
- The latter happens asynchronously (built it like this for non-blocking
with multiple workspaces), but since we restrict the email update
functionality to a single user, we can also update the email in
workspaceMember synchronously - I left asynchronous there to receive
feedback on whether we should move to synchronous or not.
- Merged main and resolved conflicts to ensure we use the
`SettingsPermissionGuard` and the updated `workspace.service.ts` code.

One edge-case that I was trying to communicate on Discord: 

Say that an admin is a member of multiple workspaces. Therefore, they
can allow roles with PROFILE_INFORMATION permission to update their
email.

<p align="center">
<img width="553" height="115" alt="image"
src="https://github.com/user-attachments/assets/80382b1f-a9e3-4dac-b606-c2defeb2c330"
/>
</p>

However, since the admin is part of multiple workspaces, he/she cannot
even update own email - the field stays disabled, leading to some
confusion.

<p align="center">
<img width="545" height="255" alt="image"
src="https://github.com/user-attachments/assets/5e6d27db-c9a8-4d5e-9ab6-65c77beae5b4"
/>
</p>

However, the workspace can have another member with admin role or some
other role that has PROFILE_INFORMATION permission flag. That user will
be and should be allowed to update email, so we cannot hide `email` from
dropdown options.

<p align="center">
<img width="585" height="283" alt="image"
src="https://github.com/user-attachments/assets/a670d3ac-cf48-4865-a425-b909093d8420"
/>
</p>

The behavior is fine imo, just a little confusing for members with more
than one workspace.

I have also tested the flow by signing up to YC workspace with my org
google account (twenty.com), then changing email to my personal address.
- After changing, I need to login using Google with my personal account
to access YC workspace again.
- If I login using Google with org google account (twenty.com), a new
user account is created.

This behavior is consistent with Notion and Linear. 

Finally, as for the verification of email, the user is asked to verify
email while they're logged in, but just in case they logout without
verifying, the next login would force them to verify their email in the
email/password flow.

However, for Social/SSO, they must verify before they logout or else
they'd have to contact support for assistance. I have not looked into
how to show verification screen while logging in via Social/SSO yet, but
if that's something critical for completeness here, I shall revisit it.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-11-13 15:00:02 +01:00
3ef9be6622 message channel change #3 (#15757)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-13 14:12:20 +01:00
Félix MalfaitandGitHub f9c61833ec Add debug info in AI chat (#15758)
## 🐛 Critical Bug Fix

### Cost Calculation Error (1000x undercharge)
- **Fixed**: Cost conversion utility was calculating credits at 1/1000th
of actual value
- **Before**: `cents * 10` 
- **After**: `(cents / 100) * DOLLAR_TO_CREDIT_MULTIPLIER` 
- **Impact**: Users were being undercharged by 1000x
  - Example: 0.75 cents should = 7,500 credits
  - Bug calculated it as 7.5 credits

---

## 🎯 Code Centralization & DRY

### Unified Cost Calculation
- Centralized all cost conversions to use `convertCentsToBillingCredits`
utility
- Refactored 3 different implementations into 1 single source of truth
- Files updated:
  - `ai-billing.service.ts`
  - `agent-streaming.service.ts` (2 usages)

**Before** (multiple implementations):
```typescript
// Wrong implementation
const credits = cents * 10;

// Verbose implementation  
const costInDollars = costInCents / 100;
const creditsUsed = Math.round(costInDollars * DOLLAR_TO_CREDIT_MULTIPLIER);
```

**After** (unified):
```typescript
const creditsUsed = Math.round(convertCentsToBillingCredits(costInCents));
```

---

##  UI Component Refactoring

### RoutingDebugDisplay.tsx
- **Reduced from 118 lines to 34 lines** (71% reduction)
- Extracted `renderTimingRow` helper to eliminate 15 repetitive JSX
blocks
- Added `formatTokenBreakdown` helper for token display logic
- Much easier to add new debug metrics

**Before**: 15 nearly-identical blocks of repetitive JSX  
**After**: Clean, DRY implementation with reusable helpers

---

## 🧹 Code Quality Improvements

### Removed Debug Code
- Removed `console.log` accidentally left in `RoutingStatusDisplay.tsx`

### Cleaned Up Comments (18+ removed)
Removed redundant comments that stated the obvious:
-  "Calculate routing cost if we have token usage"
-  "Send the updated routing status with execution metrics to the
client"
-  "Count tool calls in the response"
-  "AI SDK's LanguageModelUsage uses inputTokens/outputTokens"
- And 14+ more...

Kept meaningful comments:
-  "Timing is optional, ignore errors" (explains catch block)
-  Type definition grouping comments

---

## 📊 Statistics

**Files Modified**: 10
- `convert-cents-to-billing-credits.util.ts` (fixed formula)
- `ai-billing.service.ts` (use centralized utility)
- `agent-streaming.service.ts` (use utility, remove comments)
- `agent-execution.service.ts` (remove comments)
- `ai-router.service.ts` (remove comments)
- `RoutingStatusDisplay.tsx` (remove debug code)
- `RoutingDebugDisplay.tsx` (major refactor) 
- `isDebugModeState.ts` (new file)
- `DataMessagePart.ts` (type extensions)
- `useClientConfig.ts` (debug mode support)

**Impact**:
- Lines removed: ~130 (redundant code + comments)
- Lines added: ~45 (helper functions)
- **Net reduction**: ~85 lines
- **Bug fixes**: 1 critical (1000x cost error)
- **Centralizations**: 3 locations now using shared utility
- **Major refactors**: 1 UI component (71% reduction)

---

##  Verification

-  All linter checks pass
-  All tests pass (`ai-billing.service.spec.ts` verified)
-  No `any` types in affected code
-  No TODO/FIXME markers

---

## 🎯 Principles Applied

1.  **Fix Root Causes, Not Symptoms** - Fixed utility function, then
used it everywhere
2.  **DRY (Don't Repeat Yourself)** - Centralized cost calculation and
UI rendering
3.  **Single Source of Truth** - One place for cost conversion formula
4.  **Code as Documentation** - Removed comments that repeated what
code says
5.  **Composability** - Created reusable helper functions
6.  **Type Safety** - Maintained strict typing throughout
2025-11-13 13:34:46 +01:00
nitinandGitHub fddac24e7f connect line chart to backend (#15657)
https://github.com/user-attachments/assets/b797c5a8-32a8-4d3e-9fb1-7541d107a19f

optimizations:
before: 


https://github.com/user-attachments/assets/bf45a3f1-5f89-40c1-9ce4-c2d912b77d63


after:


https://github.com/user-attachments/assets/61bfd603-7b63-4695-8ae8-68fe7d3bfea0
2025-11-13 11:35:08 +00:00
GuillimandGitHub 0389fcf00d removing feature flag IS_MORPH_RELATION_ENABLED (#15783)
releasing the morph feature for all workspaces
2025-11-13 12:03:25 +01:00
Raphaël BosiandGitHub cb759aa22e Fix concurrent page layout edition bug (#15740)
This PR fixes a bug which could happen if two people were editing a page
layout at the same time.
If one person deletes a widget or a tab and saves first, and the second
person saves after but doesn't delete this widget or tab, an error is
raised.

This is because, in the backend, a diff is computed to know which tab or
widget to create, update or delete. But the logic was maid without
considering soft deletion. So, when the second person saves, the diff
tries to create the widget or tab which had been soft deleted by the
first use. Since they have the same id, a duplicate primary key error is
raised.

Now we always consider that the last user to save has the truth. So we
restore the tab/widget and update it.
2025-11-13 12:01:11 +01:00
Lucas BordeauandGitHub a453d53656 Fix Snackbar crashing the whole app (#15774)
This PR fixes a crash of the app when a Snackbar tries to render an
object.

<img width="3002" height="754" alt="image"
src="https://github.com/user-attachments/assets/988f97eb-5c8a-44f8-ac8e-e2953b872bac"
/>

What happened : the backend sent a MessageDescriptor in
`extensions.userFriendlyMessage` while it should have sent a translated
string.

But it is a problem that the Snackbar can end up rendering objects and
crashing the whole app because it is a the highest level in the tree.

So this PR hardens many points to avoid future bugs : 
- Sanitize what is rendered by the Snackbar to avoid any crash
- Translate any MessageDescriptor object that could end up in the
frontend
- Fix the places in the backend where a MessageDescriptor wasn't
translated and sent directly to the frontend in
`use-graphql-error-handler.hook.ts`

Fixes https://github.com/twentyhq/twenty/issues/15685
Fixes https://github.com/twentyhq/core-team-issues/issues/1869
2025-11-13 12:01:06 +01:00
Félix MalfaitandGitHub 09e89334c6 Fix Tool permissionn guard issue (#15770)
Fix a critical issue on the permission guard for tools which led to
users being denied access when they should have had access
2025-11-12 11:51:54 +01:00
065923d724 feat: Add Workflow duplicate step (#15622)
## Description

- This PR address issue
https://github.com/twentyhq/core-team-issues/issues/1800
- Added workflow duplicate option in workflow sidepanel
- Introduced DuplicateWorkflow.ts mutuation
- Updated graphql generated metadata with new duplicate type




## Visual Appearanc

<img width="1792" height="1031" alt="Screenshot 2025-11-07 at 4 46
22 PM"
src="https://github.com/user-attachments/assets/d75f99df-ae18-4b41-a5f4-21c50010cdbc"
/>


https://github.com/user-attachments/assets/3dbf73cf-f4dd-484c-94a3-29577cfbac25

---------

Co-authored-by: Devessier <baptiste@devessier.fr>
2025-11-12 10:53:25 +01:00
de978960d0 [FIx] shouldBypassPermissionChecks for workspaceMember repository (#15706)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Pass `shouldBypassPermissionChecks: true` to
`getRepositoryForWorkspace('workspaceMember')` in
`1-11-clean-orphaned-user-workspaces.command.ts` to ensure member lookup
during orphan cleanup ignores permissions.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
543fd9fc01. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-11-11 17:17:42 +01:00
Félix MalfaitandGitHub 11e07f90d2 refactor: Simplify CRUD services to leverage Common API (#15742)
## Summary

This PR refactors all Record CRUD services to use the Common API
(CommonQueryRunners) instead of directly accessing TwentyORM, achieving
**77% code reduction** while maintaining full functionality.

## Changes

### Code Reduction: -547 net lines (77%)
- **Before**: 901 lines across 5 services
- **After**: 354 lines (services + utility)
- **Deleted**: 547 lines of redundant code

### Services Simplified

| Service | Before | After | Reduction |
|---------|--------|-------|-----------|
| CreateRecordService | 142 | 59 | -83 lines |
| UpdateRecordService | 177 | 51 | -126 lines |
| DeleteRecordService | 137 | 51 | -86 lines |
| FindRecordsService | 233 | 68 | -165 lines |
| UpsertRecordService | 212 | 129 | -83 lines |

### Architecture Change

**Before:**
```
CRUD Services → TwentyORM
- Manual query building
- Manual permission checking
- Manual transformations
- Duplicated logic
```

**After:**
```
CRUD Services → CommonQueryRunners → TwentyORM
- Common API handles queries
- Common API handles permissions
- Common API handles transformations
- Single source of truth
```

### Module Dependencies Simplified

**Removed:**
- TwentyORMModule
- RecordPositionModule
- RecordTransformerModule
- WorkflowCommonModule

**Added:**
- CoreCommonApiModule
- WorkspaceMetadataCacheModule

**From 4 heavy dependencies → 2 clean dependencies**

## What Changed

### New Code
- `common-api-context-builder.util.ts` - Single shared utility (68
lines)

### Refactored Services
All services now follow a simple pattern:
1. Build Common API context
2. Call appropriate CommonQueryRunner
3. Return formatted result

Each service is now 50-120 lines instead of 140-230 lines.

### Type Fixes
- Fixed `FindRecordsParams.orderBy` type (was
`Partial<ObjectRecordOrderBy>`, now `ObjectRecordOrderBy`)
- Fixed `FindRecordsInput.gqlOperationOrderBy` type (same fix)

## Benefits

###  Code Quality
- 77% less code to maintain
- No code duplication
- Simpler, clearer logic
- Proper TypeScript types (no hacks)

###  Common API Integration
All services now get Common API benefits:
- Consistent permission checking
- Query hooks (before/after execution)
- Automatic input transformation
- Automatic position handling
- Result processing and enrichment
- Same behavior as REST/GraphQL

###  Safety Preserved
- createdBy actor metadata preserved for workflows
- All field validation maintained
- All transformations maintained
- All error handling maintained

###  No Breaking Changes
- Same external API for all services
- Workflows continue to work
- AI operations continue to work
- MCP operations continue to work

## Testing

-  TypeScript compiles
-  All files pass linting
-  No type casting hacks
-  Proper type safety throughout
- ⚠️ Integration tests recommended

## What Common API Handles For Us

1. **Record Position** - Automatic via `RecordPositionService`
2. **Input Transformation** - Automatic for NUMBER, RICH_TEXT, PHONES,
EMAILS, LINKS
3. **createdBy Actor** - Injected via `CreatedByCreateOnePreQueryHook` +
explicit workflow actor
4. **Field Validation** - Only processes valid fields
5. **Permissions** - Validates permissions before execution
6. **Query Hooks** - Before/after execution hooks work
7. **Error Handling** - Consistent exception handling

## Files Modified (12)

**Services (6):**
- create-record.service.ts
- update-record.service.ts
- delete-record.service.ts
- find-records.service.ts
- upsert-record.service.ts
- record-crud.module.ts

**Types (2):**
- find-records-params.type.ts
- record-crud-input.type.ts

**Workflows (1):**
- find-records.workflow-action.ts

**New Files (3):**
- common-api-context-builder.util.ts
- REFACTORING_COMPLETE.md
- REFACTORING_ANALYSIS.md

## Verification Checklist

- [x] TypeScript compiles
- [x] Linter passes
- [x] No type hacks (`as unknown as` removed)
- [x] createdBy preserved for workflows
- [x] Module dependencies simplified
- [x] Common API integration complete
- [ ] Integration tests pass (recommended)
- [ ] Workflow execution tested (recommended)

## Related Issues

This refactoring establishes the pattern for making CRUD operations
consistent across all presentation layers (REST, GraphQL,
Tools/Workflows/AI/MCP).
2025-11-11 11:07:36 +01:00