Commit Graph

345 Commits

Author SHA1 Message Date
Weiko 9bd8f94b3a Refactor global datasource part 3 (#16447)
## Context
Following https://github.com/twentyhq/twenty/pull/16399
Now using the new global orm manager everywhere and returning a
GlobalDatasource/WorkspaceDatasource based on a feature flag.
This means we now need to wrap all our ORM calls within
executeInWorkspaceContext callback (at least for now) so the global
datasource can dynamically hydrate its context via the new store (the
global datasource does not store anything related to workspaces as it is
now a unique singleton). If feature flag is off it still uses local data
stored in the workspace datasource.
2025-12-10 17:17:33 +01:00
Charles Bochet aa519e7d81 Fix messaging errors on message folder list (#16404)
This is a known quirk of many Google APIs, including Gmail. Some error
responses use numeric code fields (e.g., 403), while others may return
them as strings (e.g., "403"). This depends on which internal service
returns the error and the language client you’re using.
2025-12-09 17:01:25 +01:00
Paul Rastoin 4996f3dd28 Finalize twenty standard app as workspace migration object and fields (#16353)
# Introduction
Related to https://github.com/twentyhq/core-team-issues/issues/1995
In this PR we're fixing the remaining object/fields validation errors
resulting from standard objects and fields now passing a validation that
wasn't when using the sync metadata

## Key Changes
- **Field naming**: Renamed `iCalUID` to `iCalUid` for consistent
camelCase convention across calendar events
- **Enum standardization**: Uppercased enum values for message channels
(email→EMAIL), message participants (from→FROM, to→TO, cc→CC, bcc→BCC),
and message direction (incoming→INCOMING, outgoing→OUTGOING)
- **Label simplification**: Removed example values from workspace member
number format labels for cleaner UI
- **Migration infrastructure**: Added `isSystemBuild` flag throughout
field metadata service pipeline to allow system-level updates of
standard fields that bypass normal restrictions

## Migrating the existing data
We've created an upgrade command that will identify using the existing
object and field standard id field that needs to be updated, even though
the sync metadata still in usage could have fix them ( and the goal is
to deprecate it by the end of the sprint )
We will call the updateOneField for each of them, we're passing by the
field service in order to battle test what are going to be the temporary
way to handle standard migrations when we will start deprecating the
sync metadata but haven't still refactored the v2 workspace migration to
be workspace agnostic

## Twenty eng migration
Tested the whole migration + upgrade on twenty eng
Here are generated workspace migration
Records are handled natively gracefully too

### ICalUid
```json
{
  "status": "success",
  "workspaceMigration": {
    "relatedFlatEntityMapsKeys": [
      "flatFieldMetadataMaps",
      "flatIndexMaps",
      "flatViewFilterMaps",
      "flatViewGroupMaps",
      "flatViewMaps",
      "flatViewFieldMaps",
      "flatObjectMetadataMaps"
    ],
    "actions": [
      {
        "type": "update_field",
        "fieldMetadataId": "",
        "objectMetadataId": "",
        "updates": [
          {
            "from": "iCalUID",
            "to": "iCalUid",
            "property": "name"
          }
        ]
      }
    ],
    "workspaceId": ""
  }
}
```

### Incoming Outgoing
None as already caps in database somehow
```json
{
  "status": "success",
  "workspaceMigration": {
    "relatedFlatEntityMapsKeys": [
      "flatFieldMetadataMaps",
      "flatIndexMaps",
      "flatViewFilterMaps",
      "flatViewGroupMaps",
      "flatViewMaps",
      "flatViewFieldMaps",
      "flatObjectMetadataMaps"
    ],
    "actions": [],
    "workspaceId": ""
  }
}
```

### EMAIL
```json
{
  "status": "success",
  "workspaceMigration": {
    "relatedFlatEntityMapsKeys": [
      "flatFieldMetadataMaps",
      "flatIndexMaps",
      "flatViewFilterMaps",
      "flatViewGroupMaps",
      "flatViewMaps",
      "flatViewFieldMaps",
      "flatObjectMetadataMaps"
    ],
    "actions": [
      {
        "type": "update_field",
        "fieldMetadataId": "",
        "objectMetadataId": "",
        "updates": [
          {
            "from": "'email'",
            "to": "'EMAIL'",
            "property": "defaultValue"
          },
          {
            "from": [
              {
                "color": "green",
                "id": "",
                "label": "Email",
                "position": 0,
                "value": "email"
              },
              {
                "color": "blue",
                "id": "",
                "label": "SMS",
                "position": 1,
                "value": "sms"
              }
            ],
            "to": [
              {
                "color": "green",
                "id": "",
                "label": "Email",
                "position": 0,
                "value": "EMAIL"
              },
              {
                "color": "blue",
                "id": "",
                "label": "SMS",
                "position": 1,
                "value": "SMS"
              }
            ],
            "property": "options"
          }
        ]
      }
    ],
    "workspaceId": "e"
  }
}
```

### MessageParticipantRole
```json
{
  "status": "success",
  "workspaceMigration": {
    "relatedFlatEntityMapsKeys": [
      "flatFieldMetadataMaps",
      "flatIndexMaps",
      "flatViewFilterMaps",
      "flatViewGroupMaps",
      "flatViewMaps",
      "flatViewFieldMaps",
      "flatObjectMetadataMaps"
    ],
    "actions": [
      {
        "type": "update_field",
        "fieldMetadataId": "",
        "objectMetadataId": "",
        "updates": [
          {
            "from": "'from'",
            "to": "'FROM'",
            "property": "defaultValue"
          },
          {
            "from": [
              {
                "color": "green",
                "id": "",
                "label": "From",
                "position": 0,
                "value": "from"
              },
              {
                "color": "blue",
                "id": "",
                "label": "To",
                "position": 1,
                "value": "to"
              },
              {
                "color": "orange",
                "id": "",
                "label": "Cc",
                "position": 2,
                "value": "cc"
              },
              {
                "color": "red",
                "id": "",
                "label": "Bcc",
                "position": 3,
                "value": "bcc"
              }
            ],
            "to": [
              {
                "color": "green",
                "id": "",
                "label": "From",
                "position": 0,
                "value": "FROM"
              },
              {
                "color": "blue",
                "id": "",
                "label": "To",
                "position": 1,
                "value": "TO"
              },
              {
                "color": "orange",
                "id": "",
                "label": "Cc",
                "position": 2,
                "value": "CC"
              },
              {
                "color": "red",
                "id": "",
                "label": "Bcc",
                "position": 3,
                "value": "BCC"
              }
            ],
            "property": "options"
          }
        ]
      }
    ],
    "workspaceId": ""
  }
}
```

### Workspace member number format labels
```json
{
  "status": "success",
  "workspaceMigration": {
    "relatedFlatEntityMapsKeys": [
      "flatFieldMetadataMaps",
      "flatIndexMaps",
      "flatViewFilterMaps",
      "flatViewGroupMaps",
      "flatViewMaps",
      "flatViewFieldMaps",
      "flatObjectMetadataMaps"
    ],
    "actions": [
      {
        "type": "update_field",
        "fieldMetadataId": "",
        "objectMetadataId": "",
        "updates": [
          {
            "from": [
              {
                "color": "turquoise",
                "id": "",
                "label": "System",
                "position": 0,
                "value": "SYSTEM"
              },
              {
                "color": "blue",
                "id": "",
                "label": "Commas and dot (1,234.56)",
                "position": 1,
                "value": "COMMAS_AND_DOT"
              },
              {
                "color": "green",
                "id": "",
                "label": "Spaces and comma (1 234,56)",
                "position": 2,
                "value": "SPACES_AND_COMMA"
              },
              {
                "color": "orange",
                "id": "",
                "label": "Dots and comma (1.234,56)",
                "position": 3,
                "value": "DOTS_AND_COMMA"
              },
              {
                "color": "purple",
                "id": "",
                "label": "Apostrophe and dot (1'234.56)",
                "position": 4,
                "value": "APOSTROPHE_AND_DOT"
              }
            ],
            "to": [
              {
                "color": "turquoise",
                "id": "",
                "label": "System",
                "position": 0,
                "value": "SYSTEM"
              },
              {
                "color": "blue",
                "id": "",
                "label": "Commas and dot",
                "position": 1,
                "value": "COMMAS_AND_DOT"
              },
              {
                "color": "green",
                "id": "",
                "label": "Spaces and comma",
                "position": 2,
                "value": "SPACES_AND_COMMA"
              },
              {
                "color": "orange",
                "id": "",
                "label": "Dots and comma",
                "position": 3,
                "value": "DOTS_AND_COMMA"
              },
              {
                "color": "purple",
                "id": "",
                "label": "Apostrophe and dot",
                "position": 4,
                "value": "APOSTROPHE_AND_DOT"
              }
            ],
            "property": "options"
          }
        ]
      }
    ],
    "workspaceId": ""
  }
}
```
2025-12-09 14:09:48 +01:00
Weiko 859004f4fc Refactor global datasource part 2 (#16399)
## Context
Deprecating TwentyORMManager in favor of TwentyORMGlobalManager
(temporarily, as this will simplify the ultimate goal to later replace
all usages with the new TwentyORMGlobalManagerV2 which will have a
similar signature)
This means this PR had to refactor a bit of code to pass down the
workspaceId when not available directly as it is now a requirement,
meaning we also deprecated scopedWorkspaceContextFactory to have a less
obscure way to fetch the workspaceId and have something more
declarative.

Step 3 will be to update TwentyORMGlobalManager to use a featureFlag
toggling and use the new GlobalWorkspaceOrmManager internally using the
new cache service

Step 4 will be to remove the feature flag and pg_pool patch
2025-12-08 17:05:00 +01:00
Charles Bochet 2790d5dd93 Message fixes (#16389)
In this PR:
- add more logs to troubleshoot issues in production
- use messageChannelSyncStatus in messageSync service instead of making
a manual update
2025-12-08 14:56:43 +01:00
neo773 fee3e6b7a1 fix folder actions (#16344)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-12-05 16:19:50 +01:00
Charles Bochet 56e66315cd Fix messaging direct import (#16354)
Mainly clarifying naming (scheduleMessageImport was actually tagging as
PENDING)
+ tagging as SCHEDULED in case of direct import (we skip PENDING state)
2025-12-05 10:48:09 +01:00
Charles Bochet 10b5e156e5 Improvement on messaging (#16351)
In this PR:
- change messaging / calendar stale duration check to 30minutes (cron is
running every 1h, duration check was 1h, so evaluation was flaky)
- when temporary error (throttling), preserve syncStageStartedAt as this
is necessary to assess exponential throttling
2025-12-05 00:04:07 +01:00
Charles Bochet 68a9ef57f0 Fix Message/Calendar channel stuck in SCHEDULED syncStage (#16326)
As per title
2025-12-04 16:01:11 +01:00
neo773 e112eb4f69 Simplify IMAP implementation (#16295) 2025-12-04 14:32:41 +01:00
neo773 8716cb25e9 Add message channel reset command (#16266)
In this PR, we are adding a new command to reset a message channel.

We are also refactoring a bit cursor reset as we had multiple
implementations at different places in the code base

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-12-04 14:25:41 +01:00
neo773 79e2602790 Remove IS_MESSAGE_FOLDER_CONTROL_ENABLED feature flag (#16183)
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-12-01 16:29:09 +01:00
Etienne cd699cbda1 Fix message sync (#16186)
Follow up
https://twenty-v7.sentry.io/issues/7072565676/events/2068bcd0b5b642dca1215b015ac74cfd/?environment=prod&environment=prod-eu&project=4507072499810304&query=is%3Aunresolved%20%21issue.type%3A%5Bperformance_consecutive_db_queries%2Cperformance_consecutive_http%2Cperformance_file_io_main_thread%2Cperformance_db_main_thread%2Cperformance_n_plus_one_db_queries%2Cperformance_n_plus_one_api_calls%2Cperformance_p95_endpoint_regression%2Cperformance_slow_db_query%2Cperformance_render_blocking_asset_span%2Cperformance_uncompressed_assets%2Cperformance_http_overhead%2Cperformance_large_http_payload%5D%20timesSeen%3A%3E10&referrer=previous-event&sort=date
and
https://github.com/twentyhq/twenty/pull/16144/files#diff-3adef01a601936cd060128fd08874cf5938d477bfde39f306aa5070a068e07aa
2025-11-28 17:49:57 +01:00
Charles Bochet eb362c6d5f Update workspace entities to make all TEXT nullable (#16144)
Follow up on #15926

---------

Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com>
Co-authored-by: guillim <guigloo@msn.com>
2025-11-28 10:50:38 +01:00
Weiko 9620a4b0ba Optimize EntityMetadata caching in GlobalWorkspaceDataSource (#16146)
## Context
EntityMetadata was being rebuilt from scratch on every
findMetadata()/getMetadata() call (~20 times per request). This involved
running EntitySchemaTransformer.transform() and
EntityMetadataBuilder.build() repeatedly, causing unnecessary CPU
overhead.

## Implementation
Cache entityMetadatas in ORMWorkspaceContext: Build EntityMetadata once
during workspace context initialization instead of on every metadata
lookup
Remove redundant entitySchemas caching: Since flatMetadata is already
cached, the additional Redis cache for entitySchemaOptions was
unnecessary overhead
Remove WorkspaceEntitiesStorage: Replaced with direct lookup from
FlatObjectMetadataMap
Simplify getObjectMetadataFromEntityTarget: Now only accepts string
targets, using flat metadata maps directly

Also:
Removed unused injections in some services
2025-11-28 10:09:52 +01:00
Charles Bochet b1d1bcb712 Fix messaging import (#16112) 2025-11-26 23:13:12 +01:00
Charles Bochet 5202e2b2db Refactor error messages messaging (#16094)
We should try catch locally gmail errors when:
- fetching message list
- fetching messages
- refreshing aliases
- fetching folders
2025-11-26 18:03:44 +01:00
neo773 4120c191f8 fix scheduling after folder actions are processed (#16097) 2025-11-26 17:09:06 +01:00
Paul Rastoin 74eab77539 Refactor upgrade devx to allow configuring workspaces status to pass over (#16066)
# Introduction
We need to be able to create custom workspace application on all
workspaces, even pending and ongoing etc
Right now the upgrade devx only allows and expect active or suspended
workspace to be passed to runOnWorkspace.

## WorkspacesMigrationRunner
Created an intermediate class `WorkspacesMigrationRunner` that expect an
array `WorkspaceStatus` to be fetched for the current command to be run
on
The `ActiveOrSuspendedCommandRunner` statically passes both `SUSPENDED`
and `ACTIVE`, whereas the create workspace custom application passed all
the enum values

## DataSource
Workspace that are not fully init don't have a `workspace_schema` so
they don't have `dataSource`
Made a not very elegant check to see if current workspace we're about to
create dataSource on has one historically
Which means that dataSource is now optional, it had only one impact on
an existing command and the desired devx will become consuming existing
services that do not expect dataSource ( or at least yet )
2025-11-26 12:53:33 +01:00
Charles Bochet 4d0c469157 Fix message import scheduled (#16071)
Co-authored-by: neo773 <neo773@protonmail.com>
2025-11-26 08:54:53 +01:00
neo773 f3416d435c move folder cron to message-list-fetch (#16062) 2025-11-25 18:06:38 +01:00
Charles Bochet 8455ecc3e8 Add import scheduled status to messaging sync (#16058)
We have introduced to new syncStage statuses:
`messageChannel.MESSAGES_IMPORT_SCHEDULED` and
`calendarChannel.CALENDAR_EVENTS_IMPORT_SCHEDULED`

We need to make sure all existing workspaces have it
2025-11-25 15:27:58 +01:00
neo773 44c0dcde5b Message channel change 3 fix (#15986) 2025-11-23 20:56:02 +01:00
neo773 b711c11431 message channel change 4 (#15936)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-22 07:49:47 +01:00
neo773 f82325b66b handle HTTP 410,404 in GmailMessagesImportErrorHandler (#15969)
Noticed this in prod, we currently return `undefined` instead of
handling it.
2025-11-21 11:06:21 +01:00
neo773 dc3e30b115 message channel change 5 (#15964) 2025-11-21 11:05:12 +01:00
martmull 3190ca5b9e 1858 extensibility create relation metadata decorator in thwenty sdkapplications (#15907)
as title

First PR 
I will update the twenty-cli in another PR
2025-11-20 10:22:42 +01:00
neo773 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
neo773 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
neo773 347e855b1f update default message folder import policy to ALL_FOLDERS (#15858) 2025-11-18 16:59:15 +01:00
Félix Malfait 19ca93b954 Fix auth connection (#15869)
Better to do auth this way than in module
2025-11-17 18:12:48 +01:00
neo773 3ef9be6622 message channel change #3 (#15757)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-11-13 14:12:20 +01:00
martmull 9880f192a5 Move composite types to twenty-shared (#15741) 2025-11-10 22:11:52 +01:00
neo773 39017f43b8 handle invalid/expired syncCursor (#15715) 2025-11-10 18:18:17 +01:00
Paul Rastoin 7a1e699fc8 Twenty standard and workspace custom applications 1/3 (#15625)
# Introduction
related to https://github.com/twentyhq/core-team-issues/issues/1833
In this PR we're starting the sync-metadata and standardIds deprecation
by introducing `twenty-standard` application that will regroup every
standard object such as company and opportunities. But also the
`custom-workspace-application` which is an app created at the same time
as a workspace and that will regroup everything configure within the
workspace ( custom objects fields etc )

## What's done
On both new workspace and seeded workspace creation:
- Creating a custom workspace app
- Creating a twenty standard app
- Refactored the seed core schema and workspace creation to be run
within a transaction in order to handle circular dependency foreignkey
requirements ( which is deferred for app toward workspace )
- Updated workspace entity to have a custom workspace relation (
nullable for the moment until we implem an upgrade command to handle
retro comp )
- Integration testing on user, workspace creation deletion and expected
default apps creation
- ~~Soft deleted user on `deleteUser`~~ Done by marie and rebased on it

## What's next
- Update seeder to propagate the `twenty-standard` workspace
`applicationId` to every standard synchronized entities ( cheap and fast
iteration through the about to be deprecated sync-metadata as an easy
way to synchronize standards metadata entities ).
- Update seeder to propagate the `custom-workspace-application`
workspace `applicationId` to anything custom ( `pets` and `rockets` )
- Prepend `custom-workspace-application` `applicationId` to every
metadata API operations ( create a specific cache etc )
- Upgrade command on all existing workspace to create a custom app and
associate its applicationId to any existing custom entities
- Make `universalIdentifier` and `applicationId` required for any
syncable entity
2025-11-10 16:13:12 +01:00
neo773 f91c2bb729 fix exceptionHandlerService.captureExceptions in MessageImportExceptionHandlerService (#15703) 2025-11-07 15:53:26 +01:00
neo773 546fba7d05 [MESSAGING] Calendar check syncStatus in jobs (#15658) 2025-11-06 16:14:21 +01:00
martmull abde3c04ac 1630 extensibility twenty cli ability to create edit and delete fields (#15501)
As title

- adds decorators in twenty-sdk
- update twenty-cli load-manifest to it gets @FieldMetadata infos +
testing
- update twenty-server so it CRUD fields properly, using
universalIdentifier
- Fix UI so we can update managed objects records
- move FieldMetadata items from twenty-server to twenty-shared
2025-11-05 17:50:06 +01:00
neo773 0b7271ad13 refactor reconnect account logic (#15584) 2025-11-05 00:26:23 +01:00
neo773 e3076328dd Child folders followup (#15526) 2025-11-04 15:04:03 +01:00
neo773 44c0b9f94b refactor messaging error handling (#15416) 2025-11-01 20:03:41 +01:00
Charles Bochet 6cf5bd2ed4 Remove old Calendar and Messaging partial/full sync stages (#15380)
Now that all existing and new workspaces have the following syncStage:
- CALENDAR_EVENT_LIST_FETCH_PENDING
- MESSAGE_LIST_FETCH_PENDING

We can fully deprecate the old FULL_CALENDAR_EVENT_LIST_FETCH_PENDING
and PARTIAL_CALENDAR_EVENT_LIST_FETCH_PENDING (full vs partial is now
directly inferred from the presence of a cursor)
2025-10-27 17:35:10 +01:00
neo773 dc9d8db770 refactor: extract filter-emails utils into separate files (#15365) 2025-10-27 14:35:21 +01:00
neo773 e37b8b61ba message channel change 2 (#15269)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-24 16:39:22 +02:00
Harshit Singh 4b846a42a2 feat: Attachement for Send Email workflow node (#15044)
## Description

- This PR addresses the one issue out of
https://github.com/twentyhq/core-team-issues/issues/1685
-  Added backend support for workflow node to support attachement
- updated send email schema, core utility 
- added workflowattachmentRow and workflowsendEmailAttachment file to
handle file attachment in email workflow
- updated Google and Microsoft to use MailComposer which unifies with
SMTP provider and improves mail structure

## Visual Appearance



https://github.com/user-attachments/assets/16478569-0a83-417e-a85e-70e41fe83343

---------

Co-authored-by: martmull <martmull@hotmail.fr>
2025-10-22 16:45:28 +00:00
Félix Malfait c5564d9bd0 [BREAKING CHANGE] refactor: Add Entity suffix to TypeORM entity classes (#15239)
## Summary

This PR refactors all TypeORM entity classes in the Twenty codebase to
include an 'Entity' suffix (e.g., User → UserEntity, Workspace →
WorkspaceEntity) to improve code clarity and follow TypeORM naming
conventions.

## Changes

### Entity Renaming
-  Renamed **57 core TypeORM entities** with 'Entity' suffix
-  Updated all related imports, decorators, and type references
-  Fixed Repository<T>, @InjectRepository(), and
TypeOrmModule.forFeature() patterns
-  Fixed @ManyToOne/@OneToMany/@OneToOne decorator references

### Backward Compatibility
-  Preserved GraphQL schema names using @ObjectType('OriginalName')
decorators
-  **No breaking changes** to GraphQL API
-  **No database migrations** required
-  File names unchanged (user.entity.ts remains as-is)

### Code Quality
-  Fixed **497 TypeScript errors** (82% reduction from 606 to 109)
-  **All linter checks passing**
-  Improved type safety across the codebase

## Entities Renamed

```
User → UserEntity
Workspace → WorkspaceEntity
ApiKey → ApiKeyEntity
AppToken → AppTokenEntity
UserWorkspace → UserWorkspaceEntity
Webhook → WebhookEntity
FeatureFlag → FeatureFlagEntity
ApprovedAccessDomain → ApprovedAccessDomainEntity
TwoFactorAuthenticationMethod → TwoFactorAuthenticationMethodEntity
WorkspaceSSOIdentityProvider → WorkspaceSSOIdentityProviderEntity
EmailingDomain → EmailingDomainEntity
KeyValuePair → KeyValuePairEntity
PublicDomain → PublicDomainEntity
PostgresCredentials → PostgresCredentialsEntity
...and 43 more entities
```

## Impact

### Files Changed
- **400 files** modified
- **2,575 insertions**, **2,191 deletions**

### Progress
-  **82% complete** (497/606 errors fixed)
- ⚠️ **109 TypeScript errors** remain (18% of original)

## Remaining Work

The 109 remaining TypeScript errors are primarily:

1. **Function signature mismatches** (~15 errors) - Test mocks with
incorrect parameter counts
2. **Entity type mismatches** (~25 errors) - UserEntity vs
UserWorkspaceEntity confusion
3. **Pre-existing issues** (~50 errors) - Null safety and DTO
compatibility (unrelated to refactoring)
4. **Import type issues** (~10 errors) - Entities imported with 'import
type' but used as values
5. **Minor decorator issues** (~9 errors) - onDelete property
configurations

These can be addressed in follow-up PRs without blocking this
refactoring.

## Testing Checklist

- [x] Linter passing
- [ ] Unit tests should be run (CI will verify)
- [ ] Integration tests should be run (CI will verify)
- [ ] Manual testing recommended for critical user flows

## Breaking Changes

**None** - This is a pure refactoring with full backward compatibility:
- GraphQL API unchanged (uses original entity names)
- Database schema unchanged
- External APIs unchanged

## Notes

- Created comprehensive `REFACTORING_STATUS.md` documenting the entire
process
- All temporary scripts have been cleaned up
- Branch: `refactor/add-entity-suffix-to-typeorm-entities`

## Reviewers

Please review especially:
- Entity renaming patterns
- GraphQL backward compatibility
- Any areas where entity types are confused (UserEntity vs
UserWorkspaceEntity)

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-10-22 09:55:20 +02:00
neo773 c66261a38b Reuse OAuth access tokens (#15089) 2025-10-21 11:38:49 +02:00
neo773 709bdc74c3 Add child folders support for Microsoft (#15114) 2025-10-16 22:46:58 +02:00
Charles Bochet f98e4501f5 Fix translations (#15140) 2025-10-16 15:54:08 +02:00
neo773 6f49fd1911 Message channel change 1 (#14942) 2025-10-11 18:18:44 +02:00