feat: add updatedBy field to track last record modifier (#16807)

<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Implements last-modifier tracking and unified actor injection.
> 
> - New `ActorFromAuthContextService` replaces createdBy-only logic;
pre-query hooks now inject both `createdBy` and `updatedBy` on create
and `updatedBy` on update
> - Add `updatedBy` standard field to core/custom objects (e.g.,
`person`, `company`, `task`, `note`, `attachment`, `dashboard`,
`workflow`, `workflowRun`) with IDs, metadata builders, and ORM entity
fields
> - Record CRUD: `create` now sets both `createdBy` and `updatedBy`;
`update` sets `updatedBy`; workflow actions use a shared workflow actor
builder; REST base handler uses the new actor service
> - Seeder data and snapshots updated to include `updatedBy`; GraphQL
result formatting adds defaults/handling for empty composite fields
(incl. actor)
> - Frontend `useUpdateOneRecord` upserts returned record into the local
store after mutation
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1f283778e9cb28a35bf84632a1a2997250bb3131. 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>
This commit is contained in:
Abdul Rahman
2025-12-29 14:35:17 +05:30
committed by GitHub
parent 0da5cf29de
commit 01e0502fcf
58 changed files with 1516 additions and 118 deletions
@@ -73,6 +73,22 @@ exports[`Object metadata creation should fail v2 when labelPlural contains only
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -594,6 +610,27 @@ exports[`Object metadata creation should fail v2 when labelPlural contains only
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -699,6 +736,22 @@ exports[`Object metadata creation should fail v2 when labelPlural exceeds maximu
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -1220,6 +1273,27 @@ exports[`Object metadata creation should fail v2 when labelPlural exceeds maximu
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -1336,6 +1410,22 @@ exports[`Object metadata creation should fail v2 when labelSingular contains onl
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -1857,6 +1947,27 @@ exports[`Object metadata creation should fail v2 when labelSingular contains onl
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -1962,6 +2073,22 @@ exports[`Object metadata creation should fail v2 when labelSingular exceeds maxi
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -2483,6 +2610,27 @@ exports[`Object metadata creation should fail v2 when labelSingular exceeds maxi
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -2599,6 +2747,22 @@ exports[`Object metadata creation should fail v2 when labels are identical 1`] =
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -3120,6 +3284,27 @@ exports[`Object metadata creation should fail v2 when labels are identical 1`] =
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -3225,6 +3410,22 @@ exports[`Object metadata creation should fail v2 when labels with whitespaces re
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -3746,6 +3947,27 @@ exports[`Object metadata creation should fail v2 when labels with whitespaces re
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -3851,6 +4073,22 @@ exports[`Object metadata creation should fail v2 when name exceeds maximum lengt
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -4402,6 +4640,27 @@ exports[`Object metadata creation should fail v2 when name exceeds maximum lengt
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -4507,6 +4766,22 @@ exports[`Object metadata creation should fail v2 when namePlural has invalid cha
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -5028,6 +5303,27 @@ exports[`Object metadata creation should fail v2 when namePlural has invalid cha
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -5133,6 +5429,22 @@ exports[`Object metadata creation should fail v2 when namePlural is a reserved k
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -5654,6 +5966,27 @@ exports[`Object metadata creation should fail v2 when namePlural is a reserved k
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -5770,6 +6103,22 @@ exports[`Object metadata creation should fail v2 when namePlural is not camelCas
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -6297,6 +6646,27 @@ exports[`Object metadata creation should fail v2 when namePlural is not camelCas
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -6402,6 +6772,22 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -6989,6 +7375,27 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -7094,6 +7501,22 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -7669,6 +8092,27 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -7774,6 +8218,22 @@ exports[`Object metadata creation should fail v2 when nameSingular has invalid c
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -8331,6 +8791,27 @@ exports[`Object metadata creation should fail v2 when nameSingular has invalid c
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -8436,6 +8917,22 @@ exports[`Object metadata creation should fail v2 when nameSingular is a reserved
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -8981,6 +9478,27 @@ exports[`Object metadata creation should fail v2 when nameSingular is a reserved
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -9097,6 +9615,22 @@ exports[`Object metadata creation should fail v2 when nameSingular is not camelC
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -9684,6 +10218,27 @@ exports[`Object metadata creation should fail v2 when nameSingular is not camelC
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -9789,6 +10344,22 @@ exports[`Object metadata creation should fail v2 when names are identical 1`] =
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -10310,6 +10881,27 @@ exports[`Object metadata creation should fail v2 when names are identical 1`] =
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -10415,6 +11007,22 @@ exports[`Object metadata creation should fail v2 when names with whitespaces res
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
"code": "OBJECT_METADATA_NOT_FOUND",
"message": "Object metadata not found",
"userFriendlyMessage": "Field to create related object not found",
},
],
"flatEntityMinimalInformation": {
"id": Any<String>,
"name": "updatedBy",
"objectMetadataId": Any<String>,
},
"status": "fail",
"type": "create_field",
},
{
"errors": [
{
@@ -10936,6 +11544,27 @@ exports[`Object metadata creation should fail v2 when names with whitespaces res
"status": "fail",
"type": "create_view_field",
},
{
"errors": [
{
"code": "INVALID_VIEW_DATA",
"message": "Field metadata not found",
"userFriendlyMessage": "Field metadata not found",
},
{
"code": "INVALID_VIEW_DATA",
"message": "View not found",
"userFriendlyMessage": "View not found",
},
],
"flatEntityMinimalInformation": {
"fieldMetadataId": Any<String>,
"id": Any<String>,
"viewId": Any<String>,
},
"status": "fail",
"type": "create_view_field",
},
],
"viewFilter": [],
"viewGroup": [],
@@ -93,6 +93,6 @@ describe('View side effect on object creation', () => {
expectToFail: false,
});
expect(createdViewFields.length).toBe(11);
expect(createdViewFields.length).toBe(12);
});
});