ec243e98749e99ab1e2939bc5ae236a4ab130449
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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": "" } } ``` |
||
|
|
5fb7e76005 | Migrate page layout to v2 (#16364) | ||
|
|
077be7644c | Migrate page layout widget to v2 of the API (#16323) | ||
|
|
b2d785de4b |
Page layout tab v2 (#16319)
# Introduction Migrating `pageLayoutTab` to the v2 engine - Types and constants - Builder and validate - Runner Introduced a new `StrictSyncableEntity` that enforces that `universalIdentifier` and `applicationId` are defined As these entities are brand new we could enforce this rule already This still requires a migration command to associate the existing entities to custom workspace application instance and define universalIdentifier Handled retro-comp of the migration through a migration as upgrade command fallback --------- Co-authored-by: bosiraphael <raphael.bosi@gmail.com> |
||
|
|
59672e3e34 |
Migrate agent v2 (#16214)
# Introduction Closes https://github.com/twentyhq/core-team-issues/issues/1980 In this PR we migrate the agent from v1 to v2. ## New FlatRoleTargetByAgentIdMaps Derivated the `flatRoleTargetMaps` to be building a `flatRoleTargetByAgentIdMaps` to ease retrieving a roleId to associate to an agent ## Coverage Added strong coverage on both failing and successful CRU agents operations --------- Co-authored-by: Weiko <corentin@twenty.com> |
||
|
|
ee08060798 |
Improve deactivated objects & fields behaviors. (#16090)
Closes [1918](https://github.com/twentyhq/core-team-issues/issues/1918). - For the first point in the issue, we just show the deactivated entries along with the deactivated text. --- - For the second point, we show a banner and control the enabled/disabled state of save button depending on whether we're allowing the user to create table with the typed name. - For example, we do not want to allow the user to create a table with reserved name, so we disable the save button without showing a banner. - Similarly, we do not want the user to create a table with a name that already exists in the database. In this case, we show a banner and we also disable the save button. - Finally, we do not want to allow the user to create a table where singular and plural name are the same. Therefore, we disable the save button for names like `works`. --- - For the third point, if we add the delete button, it logically means that we allow the user to delete a custom object/field even it has not been deactivated yet, so did that. - Upon deleting the object/field, if we wait for the metadata to refetch before we navigate, this is what we see because the path does not exist any longer after deletion and we're waiting for refetch on the path until we navigate away. https://github.com/user-attachments/assets/dbe0569c-db88-4285-851f-22551b1ca81e - To avoid this page from appearing, I replaced awaiting refetch to not awaiting refetch and redirecting while the refetch happens in the background. - Therefore, when we delete something, there is a slight delay for when it is actually cleared out from the list, but the Not Found view does not appear on the screen. https://github.com/user-attachments/assets/47f49579-ce51-4d6a-b857-72046247bb4b - I tried optimistically removing the object/field from the metadata, but it leads to some issues (crashes the app) and I have not been able to find a solution for it yet. - Therefore, instead of getting stuck at perfection and blocking myself, I stopped getting into the issue further and created this PR by ensuring that the desired functionality works. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Display deactivated objects/fields by default, add delete actions with confirmation, and unify metadata name computation (auto-suffix reserved keywords) across front/back with conflict checks in object creation. > > - **Frontend (Settings/Data Model)**: > - **Visibility/UX**: Show `Deactivated` labels for objects/fields; filters default to include inactive (`showDeactivated`/`showInactive` true); replace field action dropdown with chevron link. > - **Delete flows**: Add delete buttons for custom objects/fields with confirmation modals and background refetch to avoid Not Found flashes. > - **Creation/Edit validation**: Add name conflict detection banner in `SettingsDataModelObjectAboutForm` and disable Save on conflicts; simplify `metadataLabelSchema` to use computed name; form fields validate on change and sync API names. > - **Shared (twenty-shared/metadata)**: > - Add `computeMetadataNameFromLabel` util (slugify+camelCase) and `RESERVED_METADATA_NAME_KEYWORDS`; auto-append `Custom` to reserved names; export constants/utilities. > - **Backend**: > - Migrate to shared `computeMetadataNameFromLabel`; update validators to use shared reserved keywords with new messages; allow deletion of active custom fields/objects (keep standard guards); adjust services/decorators accordingly. > - **Tests/Stories**: > - Update unit/integration snapshots for new reserved-name messages and behaviors; add missing i18n/router decorators in stories. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 5b126155606f6dbc8f7f91e2192cffb7bd2ebd2c. 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> Co-authored-by: Félix Malfait <felix@twenty.com> |
||
|
|
ea3c5d2d45 |
Migrate role and role target to v2 (#16009)
# 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> |
||
|
|
3190ca5b9e |
1858 extensibility create relation metadata decorator in thwenty sdkapplications (#15907)
as title First PR I will update the twenty-cli in another PR |
||
|
|
267af42412 |
Centralize v2 errors types in twenty-shared (#15358)
# Introduction Followup of https://github.com/twentyhq/twenty/pull/15331 ( Reducing size by concerns ) This PR centralizes v2 format error types in `twenty-shared` and consuming them in the existing v2 error format logic in `twenty-server` ## Next This https://github.com/twentyhq/twenty/pull/15360 handles the frontend v2 format error refactor ## Conclusion Related to https://github.com/twentyhq/core-team-issues/issues/1776 |