Commit Graph

2674 Commits

Author SHA1 Message Date
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
martmull bdf60b1680 Fix env variable definition (#14434)
as title
2025-09-11 21:45:03 +02:00
Raphaël Bosi e80c552ae7 Create the Dashboard record show page (#14423)
Closes https://github.com/twentyhq/core-team-issues/issues/1438

- Reorganized PageLayout module
- Created `DashboardRenderer` and `PageLayoutRenderer`
- Created stories for the `PageLayoutRenderer`
- Refactored the Widget components


https://github.com/user-attachments/assets/27e9ac8f-b237-4c21-8494-3fab6d65af3a
2025-09-11 18:26:26 +02:00
github-actions[bot] db6e5c78ca i18n - translations (#14429)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-11 17:32:16 +02:00
Paul Rastoin c8bfbf00d7 [CoreViewField BREAKING_CHANGES] Refactor view field service v2 and resolver (#14396)
## Introduction

### Twenty-sever

Standardizing resolver input and transpilation models + return type on
destroy and delete
~~Finally~~ Did plug everything under a feature flag and add coverage
Next will do same for the view resolver and service v2

### Twenty-front
Refactored view field service in order to use codegenerated strictly
typed mutations and adapt to new api contract
2025-09-11 15:25:36 +00:00
Weiko d9a6e7e0b1 Add flat map cache service (#14418)
## Context
Adding a new service that provides an abstract caching system for
FlatEntityMaps.
This takes care of cache invalidation and storing local and remote cache
for the map with retrieval after a comparison with map hash between
local and remote (redis).

## Implementation
Remote (redis) keys
- Flat map data:
`engine:workspace:flat-maps:{flatMapKey}:{workspaceId}:flat-map`
- Content hash:
`engine:workspace:flat-maps:{flatMapKey}:{workspaceId}:hash`

**Local Cache Hit**: If local hash matches Redis hash, return local data
**Remote Cache Hit**: If Redis has data with different hash, update
local cache
**Remote Cache Miss**: Recompute from database, store in Remote and
locally
**Invalidation**: Remove from Remote, triggering recomputation on next
access

## Usage
```typescript
@WorkspaceFlatMapCache('view') // redis key
export class WorkspaceFlatViewMapCacheService extends WorkspaceFlatMapCacheService<FlatViewMaps> {
  constructor(
    @InjectCacheStorage(CacheStorageNamespace.EngineWorkspace)
    cacheStorageService: CacheStorageService,
    @InjectRepository(ViewEntity)
    private readonly viewRepository: Repository<ViewEntity>,
  ) {
    super(cacheStorageService);
  }

  // only method to implement
  public async computeFlatMap(workspaceId: string): Promise<FlatViewMaps> {
    const views = await this.viewRepository.find({
      where: { workspaceId },
      relations: ['viewFields'],
      select: { viewFields: { id: true } },
    });

    return generateFlatViewMaps(views);
  }
}
```

```typescript
// 2 public methods, getExistingOrRecomputeFlatMaps to fetch the map and invalidateCache after a mutation 
  await this.workspaceFlatViewMapCacheService.invalidateCache(
    viewData.workspaceId,
  );

  const flatViewMaps =
    await this.workspaceFlatViewMapCacheService.getExistingOrRecomputeFlatMaps(
      workspaceId,
    );
```

## Multi-Pod Synchronization
- Each pod maintains local cache for performance
- SHA256 hash of flatMap content used for version comparison
- `invalidateCache()` reset Redis data, forcing other pods to refresh
when calling getExistingOrRecomputeFlatMaps

--- 
<img width="1072" height="325" alt="Screenshot 2025-09-11 at 15 04 48"
src="https://github.com/user-attachments/assets/ed6ce82c-db35-4a1b-8a4e-247b694e2ddf"
/>
<img width="1030" height="328" alt="Screenshot 2025-09-11 at 15 04 40"
src="https://github.com/user-attachments/assets/43a15789-7f27-4104-a9bb-bef19908a5cd"
/>

Next step: Implement a locking mechanism by reusing existing WithLock
decorator
2025-09-11 16:54:21 +02:00
Naifer 39326e6144 feat: add FormData, text, and none body types to HTTP request workflow (#14055)
This PR is a cleaned-up and improved version of #13982, excluding file
uploads for FormData.


https://github.com/user-attachments/assets/a85546f6-4e3b-4654-a4ea-e76a11016b96

---------

Co-authored-by: Thomas Trompette <thomas.trompette@sfr.fr>
2025-09-11 14:32:19 +02:00
github-actions[bot] d2ebd870df i18n - translations (#14413)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-11 12:34:09 +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
Thomas Trompette fb43827031 Add empty workflow action (#14399)
As title
2025-09-10 18:06:19 +02:00
Thomas Trompette 3bfb5bbd86 Add duplicate step action (#14392)
https://github.com/user-attachments/assets/ac89440c-6f84-4d2a-b88a-da7ddfb181eb
2025-09-10 15:25:40 +00:00
github-actions[bot] bcf1bba302 i18n - translations (#14397)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-10 17:01:11 +02:00
Weiko 61f1a883a0 Add workspace migration orchestrator + refactor builders + view/viewField action builders (#14383) 2025-09-10 16:55:30 +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 cb0552a983 fix ci - Addd page layout rest metadata schema (#14381) 2025-09-10 11:44:38 +05:30
Marie 5900a171f1 Enable filtering out of expected 400 errors (#14371)
We decided to send 4xx errors to sentry from the FE, except for
ForbiddenErrors.
In some cases, we also need not to send to sentry some 4xx errors, like
user input error, because the error stemming from the user input is
unpredictable (ex: duplicate entry for a record with unicity
constraints) and thus acceptable.

Let's add a isExpected extension on UserInputErrors to introduce a
specific behaviour for them (do not send to sentry).
2025-09-09 19:30:56 +02:00
nitin 4ba1bd24f0 remove IS_API_KEY_ROLES_ENABLED feature flag (#14366) 2025-09-09 19:29:29 +02:00
Thomas Trompette 2b59198a1b Migrate output schema to V2 (#14311)
Previous refacto was creating output schema V2 which has more specific
schemas based on the step type. Before we were using one common schema,
which was too complex when searching for variable informations.

This PR migrate the deprecated schemas and remove the old code:
- mark previous `BaseOutputSchema` as deprecated
- remove other previous schemas
- use V2 everywhere
- icon should not be stored in schema. Instead it should be generated
based on the fieldmetadata or the item type
2025-09-09 18:37:00 +02:00
github-actions[bot] dc867e6e3e i18n - translations (#14370)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-09 15:01:16 +02:00
Raphaël Bosi 3d2d14eb71 Pre hook for dashboard creation + updates on the entity (#14354)
Closes https://github.com/twentyhq/core-team-issues/issues/1417

- The pre-hook creates a page-layout and links it to the dashboard
- Added `position`, `createdBy`, `attachments`, `searchVector`,
`favorites` to the dashboard entity
- Updated the view seed
- Updated the page layout services to work within a transaction
2025-09-09 12:55:22 +00:00
Paul Rastoin 861cb1c222 fix(server): morph relation fields filtering (#14365)
Tested: object metadata items retrieval and standard overrides
Please be sure to cache flush before testing this for the data loader to
be hit
2025-09-09 10:47:07 +00:00
github-actions[bot] fe27f321a9 i18n - translations (#14362)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-09 10:49:09 +02:00
Etienne 719be52b53 Upsert - fixes (#14358)
- add more explicit error message on upsert conflicts
- increase MAX_RECORDS_QUERY constant
- add soft deleted records when returning upserted records




fixes https://github.com/twentyhq/private-issues/issues/300
2025-09-09 08:44:07 +00:00
Thomas Trompette 7094f0ee08 Remove is branch enabled feature flag (#14357)
As title
2025-09-09 10:07:20 +02:00
Paul Rastoin 7bcbaee0c8 Fix get time on non date var (#14361) 2025-09-09 09:59:55 +02:00
Félix Malfait f7cde28dd6 🔧 Restore PRs #14348 and #14352 that were reverted by PR #14347 (#14359)
## Problem

**CRITICAL:** Two PRs were accidentally reverted when PR #14347 "Prevent
csv export injections" was merged:

1. **PR #14348** "[Page Layout] - Review Refactor" -  **RESTORED**
2. **PR #14352** "Fix wrong path used by backend" -  **RESTORED**

## Root Cause Analysis

During the merge of PR #14347, there was a complex merge conflict with
PR #14352 "Fix wrong path used by backend". The merge commit
`324d7204bb` in the PR #14347 branch brought in changes from PR #14352,
but during the conflict resolution, **BOTH PR #14348 and PR #14352's
changes were accidentally overwritten**.

## What This PR Restores

This PR restores **BOTH** PRs by cherry-picking their commits:

###  PR #14348 Changes Restored:
- `GraphWidgetRenderer.tsx` - was deleted, now restored
- `WidgetRenderer.tsx` - was missing, now restored  
- `SettingsPageLayoutTabsInstanceId.ts` - was deleted, now restored
- `useUpdatePageLayoutWidget.ts` - was renamed back, now restored with
correct name
- Multiple test files that were deleted
- Several hook files that were renamed/reverted
- File renames: `usePageLayoutWidgetUpdate.ts` →
`useUpdatePageLayoutWidget.ts`
- Hook refactoring and test file organization
- Page layout component improvements

###  PR #14352 Changes Restored:
- **Types moved to twenty-shared:**
  - `packages/twenty-shared/src/types/AppBasePath.ts`  RESTORED
  - `packages/twenty-shared/src/types/AppPath.ts`  RESTORED
  - `packages/twenty-shared/src/types/SettingsPath.ts`  RESTORED
- **Navigation utilities moved to twenty-shared:**
- `packages/twenty-shared/src/utils/navigation/getAppPath.ts`  RESTORED
- `packages/twenty-shared/src/utils/navigation/getSettingsPath.ts` 
RESTORED
- **200+ import statements updated** across the codebase to use
twenty-shared
- **Old type files deleted** from twenty-front/src/modules/types/

## Evidence of Complete Restoration

**Before (reverted state):**
-  Types were in `packages/twenty-front/src/modules/types/`
-  Page layout files missing
-  Hook files incorrectly named

**After (this PR):**
-  Types correctly in `packages/twenty-shared/src/types/`
-  All page layout files restored
-  Hook files correctly named
-  All import statements updated

## Verification

**Total changes:**
- PR #14348: 36 files changed, 863 insertions(+), 442 deletions(-)
- PR #14352: 243 files changed, 492 insertions(+), 461 deletions(-)
- **Combined: 279 files changed, 1355 insertions(+), 903 deletions(-)**

## Impact

This completely restores both PRs that were accidentally lost, ensuring:
1. Page layout refactoring work is back
2. Type organization and path utilities are correctly in twenty-shared
3. Backend email paths work correctly again
4. No functionality is lost

Fixes the reversion caused by the merge conflict in PR #14347.

---------

Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
2025-09-08 21:48:13 +02:00
Paul Rastoin ebc48e3bb2 Remove unused utils from v2 (#14356) 2025-09-08 18:16:50 +02:00
Félix Malfait cebcf4f1f5 Prevent csv export injections (#14347)
**Small Security Issue:** CSV exports were vulnerable to formula
injection attacks when users entered values starting with =, +, -, or @.
(only happens if a logged-in user injects corrupted data)

Solution:
- Added ZWJ (Zero-Width Joiner) protection that prefixes dangerous
values with invisible Unicode character
- This is the best way to preserve original data while preventing Excel
from executing formulas
- Added import cleanup to restore original values when re-importing
 
Changes:
- New sanitizeValueForCSVExport() function for security
- Updated all CSV export paths to use both security + formatting
functions
- Added comprehensive tests covering attack vectors and international
characters
- Also added cursor rules for better code consistency

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-09-08 17:57:46 +02:00
nitin 374b5dce66 Fix REST API view name template replacement (#14244)
REST API was returning raw template strings like 'All
{objectLabelPlural}' instead of replaced values. GraphQL had proper
handling but REST controllers don't have access to DataLoaders.

Added minimal template replacement using WorkspaceMetadataCacheService
to replace {objectLabelPlural} placeholders with actual object labels.
No full translations since REST isn't priority for i18n.

addressing -
https://discord.com/channels/1130383047699738754/1412122807281651833
2025-09-08 17:51:30 +02:00
neo773 ad944e1d2c merge records composite type (#14005)
/closes #13989

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-09-08 17:50:26 +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
Raphaël Bosi 49ee73a16c Update open api with page layout (#14355)
Closes https://github.com/twentyhq/core-team-issues/issues/1396
2025-09-08 17:19:06 +02:00
Charles Bochet a758154690 Add clean workspace cron command (#14353) 2025-09-08 16:46:31 +02:00
Félix Malfait 502bd07db9 Fix wrong path used by backend (#14352)
After moving a section on the frontend, this broke the path that was
sent by email on the backend.
This kind of error comes back every ~2-3 month under different forms so
we need a more robust solution: I moved routes to the shared folder,
that way we will share one common source of truth between the frontend
and the backend.

Fixes #14343
2025-09-08 16:07:13 +02:00
Charles Bochet 9fe88c2639 Messaging cleaning fixes (#14345) 2025-09-08 00:25:45 +02:00
Charles Bochet f9677122b6 Improve Messaging Gmail experience (#14342)
In this PR, I'm solving several issues:
1) We were not checking if the currentWorkspaceMember was owning the
message in the thread. It kind of worked before because the case of
shared threads (with shared threads visibility restriction) was not
happening that often. It seems that the bug has always been there
2) Re-implement orphan messages and threads deletion on messageChannel
deletion. We used to brutally look for all orphans, we disabled it last
week because it was too heavy on db. I've re-implemented it more
carefully and "surgically"
3) Gmail sync was not handling folder synced correctly. It was
leveraging labelIds which it shouldn't do (this is a AND AND parameter)
in full sync
4) Added a command to clean orphan message threads manually if needed.
Usually this is done when you remove a messageChannel, or change
blocklist rules but it can be useful to have it to debug
2025-09-07 20:36:28 +02:00
Harshit Singh b78d139db5 fix: Server-level impersonation doesn't bypass 2FA when enabled (#14340)
## Description

- This PR solves the a sub-issue from
https://github.com/twentyhq/core-team-issues/issues/1421
- impersonation tokens bypasses 2FA as intended 
- Added Audit trails to cover all impersonation events
- Added Proper testing coverage

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-09-07 15:53:23 +02:00
Thomas Trompette e8511a4da0 Fix flaky test (#14331)
Test was failing the 15th of each month
2025-09-05 18:50:07 +02:00
Charles Bochet 286682c197 DevXP improvements on new views (#14330) 2025-09-05 18:49:20 +02:00
Raphaël Bosi 9445256eee Create PageLayoutWidget resolver and controller (#14315)
Closes https://github.com/twentyhq/core-team-issues/issues/1395
2025-09-05 16:59:51 +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
github-actions[bot] 22157be640 i18n - translations (#14324)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-05 14:12:26 +02:00
github-actions[bot] 3bc86cdc10 i18n - translations (#14321)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-05 12:46:05 +02:00
Félix Malfait d5f88e566c Get ready for 1000+ members (#14313)
The goal of this PR is to test if Twenty can support a large number of
members, a question which was raised by a large company that is
considering moving away from Salesforce.

I was expecting the currentWorkspaceMembersState to cause a lot more
issue. It would be very hard to get rid of it in the context of actors,
I think that would require a big refactoring. I thought we'd have to do
it but it turns out the perf are pretty good. One thing we need to
improve is the pagination on the roles page, we'll wait for @Bonapara to
update that
2025-09-05 12:37:22 +02:00
github-actions[bot] 094d670590 i18n - translations (#14320)
Created by Github action

---------

Co-authored-by: github-actions <github-actions@twenty.com>
2025-09-05 12:20:51 +02:00
Paul Rastoin 17c646f9d8 Fix views integration tests (#14317)
Following https://github.com/twentyhq/twenty/pull/14202
2025-09-05 10:16:40 +00: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
Marie 40251d34ec [permissions] Deprecate ObjectsPermissionsDeprecated (1/3) (#14306)
We want to update UserWorkspacePermissions from 
```
export type UserWorkspacePermissions = {
  permissionFlags: Record<PermissionFlagType, boolean>;
  objectRecordsPermissions: Record<PermissionsOnAllObjectRecords, boolean>;
  objectPermissions: ObjectsPermissionsDeprecated;
};
```

to
```
export type UserWorkspacePermissions = {
  permissionFlags: Record<PermissionFlagType, boolean>;
  objectsPermissions: ObjectsPermissions;
};
```

`ObjectsPermissionsDeprecated` and `ObjectsPermissions` are actually
very similar, they only have different key names (`canRead` vs
`canReadObjectRecords`)

To avoid brutal breaking changes, we will proceed in multiple steps: 

1. This PR: adapt FE so it does not call objectRecordsPermissions
anymore + add the new objectsPermissions to UserWorkspacePermissions
without calling it yet in the FE
2. Remove objectRecordsPermissions in BE + use objectsPermissions in FE
instead of objectPermissions
3. Remove objectPermissions
2025-09-04 14:03:33 +00:00