# Introduction
In this PR we're refactoring the `FlatEntity` type to become a superset
of the `UniversalFlatEntity`.
Right now we're storing all the extra properties in `__universal`
property, at some point it might just be sibling to other entity and we
might rely on the `propertiesToCompare` constants and TypeScript
allowing passing a superset type into a smaller subset type
## FromTo utils
The entity to flat entity method now computes the universal information,
standardized a typing and pattern to do
## Example
Also strictly type
```ts
"bbb019ea-6205-498c-aea5-67bc53bce8a9": {
"workspaceId": "20202020-1c25-4d02-bf25-6aeccf7ea419",
"universalIdentifier": "20202020-d111-4d11-8d11-da5ab0a11002",
"applicationId": "d01b010d-b984-465b-b40b-370e954e5188",
"id": "bbb019ea-6205-498c-aea5-67bc53bce8a9",
"pageLayoutTabId": "791a512f-169f-4209-b731-aa86716668c6",
"title": "Deals by Company",
"type": "GRAPH",
"objectMetadataId": "9e14efea-df5b-4c0e-aba9-cfe455f32397",
"gridPosition": { "row": 0, "column": 6, "rowSpan": 6, "columnSpan": 6 },
"configuration": {
"color": "orange",
"orderBy": "FIELD_ASC",
"timezone": "UTC",
"displayLegend": true,
"displayDataLabel": false,
"showCenterMetric": true,
"configurationType": "PIE_CHART",
"firstDayOfTheWeek": 0,
"aggregateOperation": "COUNT",
"groupBySubFieldName": "name",
"groupByFieldMetadataId": "6673ff18-63d2-47a1-8f85-2b9b09ca27a5",
"aggregateFieldMetadataId": "8d64ee41-5dd4-4de6-945a-7c0c18399715"
},
"createdAt": "2026-01-28T14:08:52.140Z",
"updatedAt": "2026-01-28T14:08:52.140Z",
"deletedAt": null,
"__universal": {
"universalIdentifier": "20202020-d111-4d11-8d11-da5ab0a11002",
"applicationUniversalIdentifier": "20202020-64aa-4b6f-b003-9c74b97cee20",
"pageLayoutTabUniversalIdentifier": "20202020-d011-4d11-8d11-da5ab0a01001",
"objectMetadataUniversalIdentifier": "20202020-9549-49dd-b2b2-883999db8938",
"gridPosition": {
"row": 0,
"column": 6,
"rowSpan": 6,
"columnSpan": 6
},
"configuration": {
"color": "orange",
"orderBy": "FIELD_ASC",
"timezone": "UTC",
"displayLegend": true,
"displayDataLabel": false,
"showCenterMetric": true,
"configurationType": "PIE_CHART",
"firstDayOfTheWeek": 0,
"aggregateOperation": "COUNT",
"groupBySubFieldName": "name",
"aggregateFieldMetadataUniversalIdentifier": "20202020-d01a-4131-8a31-f123456789ab",
"groupByFieldMetadataUniversalIdentifier": "20202020-cbac-457e-b565-adece5fc815f"
}
}
},
```
# Introduction
Followup of
https://github.com/twentyhq/twenty/pull/17001#pullrequestreview-3638508738
close https://github.com/twentyhq/core-team-issues/issues/1910
We've completely decom the `sync-metadata` in production. We're now then
removing its implementation in favor of the v2.
## TODO:
- [x] Remove sync-metadata implem and commands
- [x] Remove workspace decorators
- [x] Type each deprecated field to deprecated on their workspaceEntity
- [x] Remove the `workspace-sync-metadata` folder entirely
- [x] remove workspace migration
- [x] workspace migration removal migration
- [x] remove the `v2` references from workspace manager file names
- [x] remove the `v2` references from workspace manager modules
- [ ] Double check impact on translation file path updates
## Note
- Removed the gate logic
- Remains some service v2 naming, serverless needs to be migrated on v2
fully
- Removed workspaceMigration service app health consumption, making it
always returning up ( no more down ) cc @FelixMalfait ( quite obsolete
health check now, will require complete refactor once we introduce inter
app dependency etc )
## Context
We've recently introduced a new workspace cache service which now acts
as a cache access and local storage for all workspace related data,
deprecating the individual specific services.
- Better performance through multiple caching/fetching strategies
- Consistent data access patterns across the codebase
- Reduced redis queries through MGET/MSET/PIPELINE with multiple cache
keys
# Introduction
close https://github.com/twentyhq/core-team-issues/issues/1930
close https://github.com/twentyhq/core-team-issues/issues/1929
Migrating role and roleTarget entities to the v2 core engine, allowing
v2 caching leverage and allow migrating agent to v2 that needs role
target in prior
After agent we should be able to pass twenty standard app totally though
workspace migration
## Role target assignation
Please note that role target have 3 creation entrypoints:
- Agent
- User workspace
- ApiKey
Refactored all 3 of them to pass through a new role-target.service.ts
that consumes the v2 under the hood.
---------
Co-authored-by: Weiko <corentin@twenty.com>