720348c583
--- prastoin edit ## Introduction As we're deprecating the sync metadata we cannot rely on it anymore in order to create the new standard updatedBy field In this PR we introduce a command that will backfill the dynamic field on both workspace standard and custom objects, for standard object it will create a standard fields ( twenty-standard app scoped ) and for custom one it will create a custom field ( worksapce-custom-app scoped ) ## Testing method Checkout `1.14.0` `yarn` and `npx nx database:reset twenty-server` checkout PR and `yarn` `npx nx build twenty-server` and `yarn database:migrate:prod` finally running the command #### Before <img width="2244" height="1464" alt="image" src="https://github.com/user-attachments/assets/2fb866cd-13b8-4152-99b8-1fcc813b1d46" /> #### After <img width="2244" height="1464" alt="image" src="https://github.com/user-attachments/assets/b836ac06-c7b8-4add-bee1-bc1963418f29" /> #### Logs ```ts [Nest] 20678 - 12/30/2025, 1:47:35 PM LOG [BackfillUpdatedByFieldCommand] Found 12 objects that need updatedBy field [EntityBuilder fieldMetadata] matrix computation: 3.994ms [EntityBuilder fieldMetadata] creation validation: 1.822ms [EntityBuilder fieldMetadata] deletion validation: 0.016ms [EntityBuilder fieldMetadata] update validation: 0.009ms [EntityBuilder fieldMetadata] entity processing: 6.098ms [EntityBuilder fieldMetadata] validateAndBuild: 10.217ms [EntityBuilder index] matrix computation: 0.857ms [EntityBuilder index] creation validation: 0.003ms [EntityBuilder index] deletion validation: 0.017ms [EntityBuilder index] update validation: 0.008ms [EntityBuilder index] entity processing: 4.721ms [EntityBuilder index] validateAndBuild: 5.632ms [Runner] Initial cache retrieval: 0.07ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 7.69ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 10.531ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 5.354ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 6.134ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 2.507ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 3.745ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.113ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 1.585ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.223ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.221ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 5.375ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 5.943ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.363ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 1.997ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 2.03ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.982ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 0.88ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.977ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 9.638ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 11.297ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.581ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.248ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 0.847ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 1.732ms [Runner] Transaction execution: 82.555ms [Runner] Cache invalidation flatFieldMetadataMaps,flatIndexMaps,flatObjectMetadataMaps: 89.247ms [Runner] Total execution: 171.963ms [Nest] 20678 - 12/30/2025, 1:47:35 PM LOG [BackfillUpdatedByFieldCommand] Successfully backfilled updatedBy field for 12 objects in workspace 20202020-1c25-4d02-bf25-6aeccf7ea419 [Nest] 20678 - 12/30/2025, 1:47:35 PM LOG [BackfillUpdatedByFieldCommand] Running command on workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db 2/2 [Nest] 20678 - 12/30/2025, 1:47:35 PM LOG [BackfillUpdatedByFieldCommand] Starting backfill of updatedBy field for workspace 3b8e6458-5fc1-4e63-8563-008ccddaa6db [Nest] 20678 - 12/30/2025, 1:47:35 PM LOG [BackfillUpdatedByFieldCommand] Found 10 objects that need updatedBy field [EntityBuilder fieldMetadata] matrix computation: 3.224ms [EntityBuilder fieldMetadata] creation validation: 0.969ms [EntityBuilder fieldMetadata] deletion validation: 0.014ms [EntityBuilder fieldMetadata] update validation: 0.002ms [EntityBuilder fieldMetadata] entity processing: 5.149ms [EntityBuilder fieldMetadata] validateAndBuild: 8.472ms [EntityBuilder index] matrix computation: 0.785ms [EntityBuilder index] creation validation: 0.002ms [EntityBuilder index] deletion validation: 0.014ms [EntityBuilder index] update validation: 0.002ms [EntityBuilder index] entity processing: 3.818ms [EntityBuilder index] validateAndBuild: 4.637ms [Runner] Initial cache retrieval: 0.05ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 2.964ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 3.902ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.502ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.039ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 2.673ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 3.403ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.143ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.123ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 2.033ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.954ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.826ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.903ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.495ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.106ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 14.014ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 14.373ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 1.669ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 2.48ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForMetadata: 0.62ms [BaseWorkspaceMigrationRunnerActionHandlerService] create_field executeForWorkspaceSchema: 1.048ms [Runner] Transaction execution: 73.222ms [Runner] Cache invalidation flatFieldMetadataMaps,flatIndexMaps,flatObjectMetadataMaps: 37.703ms [Runner] Total execution: 111.071ms ``` --- --------- Co-authored-by: prastoin <paul@twenty.com>
67 lines
2.5 KiB
TypeScript
67 lines
2.5 KiB
TypeScript
import { extractAndSanitizeObjectStringFields } from 'twenty-shared/utils';
|
|
|
|
import { type CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
|
|
import { generateDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/generate-default-value';
|
|
import { generateNullable } from 'src/engine/metadata-modules/field-metadata/utils/generate-nullable';
|
|
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
|
|
|
type GetDefaultFlatFieldMetadataArgs = {
|
|
fieldMetadataId: string;
|
|
createFieldInput: Omit<CreateFieldInput, 'workspaceId'>;
|
|
workspaceId: string;
|
|
workspaceCustomApplicationId: string;
|
|
};
|
|
export const getDefaultFlatFieldMetadata = ({
|
|
createFieldInput,
|
|
fieldMetadataId,
|
|
workspaceId,
|
|
workspaceCustomApplicationId,
|
|
}: GetDefaultFlatFieldMetadataArgs) => {
|
|
const { defaultValue, settings } = extractAndSanitizeObjectStringFields(
|
|
createFieldInput,
|
|
['defaultValue', 'settings'],
|
|
);
|
|
|
|
const createdAt = new Date().toISOString();
|
|
|
|
return {
|
|
calendarViewIds: [],
|
|
mainGroupByFieldMetadataViewIds: [],
|
|
viewFieldIds: [],
|
|
description: createFieldInput.description ?? null,
|
|
id: fieldMetadataId,
|
|
icon: createFieldInput.icon ?? null,
|
|
isActive: true,
|
|
isCustom: true,
|
|
isLabelSyncedWithName: createFieldInput.isLabelSyncedWithName ?? false,
|
|
isNullable: generateNullable(
|
|
createFieldInput.isNullable,
|
|
createFieldInput.isRemoteCreation,
|
|
),
|
|
isSystem: createFieldInput.isSystem ?? false,
|
|
isUnique: createFieldInput.isUnique ?? false,
|
|
label: createFieldInput.label,
|
|
name: createFieldInput.name,
|
|
objectMetadataId: createFieldInput.objectMetadataId,
|
|
relationTargetFieldMetadataId: null,
|
|
relationTargetObjectMetadataId: null,
|
|
standardId: createFieldInput.standardId ?? null,
|
|
standardOverrides: null,
|
|
type: createFieldInput.type,
|
|
universalIdentifier:
|
|
createFieldInput.universalIdentifier ?? fieldMetadataId,
|
|
workspaceId,
|
|
options: createFieldInput.options ?? null,
|
|
defaultValue: defaultValue ?? generateDefaultValue(createFieldInput.type),
|
|
settings: settings ?? null,
|
|
createdAt,
|
|
updatedAt: createdAt,
|
|
isUIReadOnly: createFieldInput.isUIReadOnly ?? false,
|
|
morphId: null,
|
|
applicationId:
|
|
createFieldInput.applicationId ?? workspaceCustomApplicationId,
|
|
viewFilterIds: [],
|
|
kanbanAggregateOperationViewIds: [],
|
|
} as const satisfies FlatFieldMetadata;
|
|
};
|