From e0b94d2b9908c3fb3cf97fa467e17a57853f1bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Magrin?= Date: Tue, 12 Mar 2024 14:26:44 +0100 Subject: [PATCH] feat: implement standardId for sync command --- .../migrations/1709894431938-addStandardId.ts | 6 - .../relation-metadata.entity.ts | 3 - .../commands/add-standard-id.command.ts | 157 +++++++ ...workspace-sync-metadata-commands.module.ts | 7 +- .../comparators/workspace-field.comparator.ts | 30 +- .../constants/standard-field-ids.ts | 387 +++++++++--------- .../constants/standard-object-ids.ts | 52 +-- .../decorators/field-metadata.decorator.ts | 10 +- .../partial-object-metadata.interface.ts | 3 +- ...puted-relation-field-metadata.interface.ts | 1 + .../workspace-sync-field-metadata.service.ts | 1 - .../workspace-sync-object-metadata.service.ts | 13 +- ...orkspace-sync-relation-metadata.service.ts | 2 + .../activity-target.object-metadata.ts | 1 + .../attachment.object-metadata.ts | 1 + .../favorite.object-metadata.ts | 1 + .../utils/compute-standard-object.util.ts | 10 +- .../utils/create-deterministic-uuid.util.ts | 10 + .../utils/sync-metadata.util.ts | 7 +- .../workspace-sync-metadata.module.ts | 2 +- 20 files changed, 448 insertions(+), 256 deletions(-) create mode 100644 packages/twenty-server/src/workspace/workspace-sync-metadata/commands/add-standard-id.command.ts create mode 100644 packages/twenty-server/src/workspace/workspace-sync-metadata/utils/create-deterministic-uuid.util.ts diff --git a/packages/twenty-server/src/database/typeorm/metadata/migrations/1709894431938-addStandardId.ts b/packages/twenty-server/src/database/typeorm/metadata/migrations/1709894431938-addStandardId.ts index 007424a459f37..e02e1b321278f 100644 --- a/packages/twenty-server/src/database/typeorm/metadata/migrations/1709894431938-addStandardId.ts +++ b/packages/twenty-server/src/database/typeorm/metadata/migrations/1709894431938-addStandardId.ts @@ -4,9 +4,6 @@ export class AddStandardId1709894431938 implements MigrationInterface { name = 'AddStandardId1709894431938'; public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `ALTER TABLE "metadata"."relationMetadata" ADD "standardId" uuid`, - ); await queryRunner.query( `ALTER TABLE "metadata"."objectMetadata" ADD "standardId" uuid`, ); @@ -22,8 +19,5 @@ export class AddStandardId1709894431938 implements MigrationInterface { await queryRunner.query( `ALTER TABLE "metadata"."objectMetadata" DROP COLUMN "standardId"`, ); - await queryRunner.query( - `ALTER TABLE "metadata"."relationMetadata" DROP COLUMN "standardId"`, - ); } } diff --git a/packages/twenty-server/src/metadata/relation-metadata/relation-metadata.entity.ts b/packages/twenty-server/src/metadata/relation-metadata/relation-metadata.entity.ts index dc330edf50c27..6b6f8f6573b06 100644 --- a/packages/twenty-server/src/metadata/relation-metadata/relation-metadata.entity.ts +++ b/packages/twenty-server/src/metadata/relation-metadata/relation-metadata.entity.ts @@ -32,9 +32,6 @@ export class RelationMetadataEntity implements RelationMetadataInterface { @PrimaryGeneratedColumn('uuid') id: string; - @Column({ nullable: true, type: 'uuid' }) - standardId: string | null; - @Column({ nullable: false }) relationType: RelationMetadataType; diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/commands/add-standard-id.command.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/commands/add-standard-id.command.ts new file mode 100644 index 0000000000000..318f5e70024ef --- /dev/null +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/commands/add-standard-id.command.ts @@ -0,0 +1,157 @@ +import { Logger } from '@nestjs/common'; +import { InjectDataSource } from '@nestjs/typeorm'; + +import { Command, CommandRunner } from 'nest-commander'; +import { DataSource } from 'typeorm'; + +import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity'; +import { FieldMetadataEntity } from 'src/metadata/field-metadata/field-metadata.entity'; +import { standardObjectMetadataDefinitions } from 'src/workspace/workspace-sync-metadata/standard-objects'; +import { StandardObjectFactory } from 'src/workspace/workspace-sync-metadata/factories/standard-object.factory'; +import { computeStandardObject } from 'src/workspace/workspace-sync-metadata/utils/compute-standard-object.util'; +import { StandardFieldFactory } from 'src/workspace/workspace-sync-metadata/factories/standard-field.factory'; +import { CustomObjectMetadata } from 'src/workspace/workspace-sync-metadata/custom-objects/custom.object-metadata'; + +@Command({ + name: 'workspace:add-standard-id', + description: 'Add standard id to all metadata objects and fields', +}) +export class AddStandardIdCommand extends CommandRunner { + private readonly logger = new Logger(AddStandardIdCommand.name); + + constructor( + @InjectDataSource('metadata') + private readonly metadataDataSource: DataSource, + private readonly standardObjectFactory: StandardObjectFactory, + private readonly standardFieldFactory: StandardFieldFactory, + ) { + super(); + } + + async run(): Promise { + const queryRunner = this.metadataDataSource.createQueryRunner(); + + await queryRunner.connect(); + await queryRunner.startTransaction(); + + const manager = queryRunner.manager; + + this.logger.log('Adding standardId to metadata objects and fields'); + + try { + const standardObjectMetadataCollection = + this.standardObjectFactory.create( + standardObjectMetadataDefinitions, + { + // We don't need to provide the workspace id and data source id as we're only adding standardId + workspaceId: '', + dataSourceId: '', + }, + { + IS_BLOCKLIST_ENABLED: true, + IS_CALENDAR_ENABLED: true, + IS_SELF_BILLING_ENABLED: true, + }, + ); + const standardFieldMetadataCollection = this.standardFieldFactory.create( + CustomObjectMetadata, + { + workspaceId: '', + dataSourceId: '', + }, + { + IS_BLOCKLIST_ENABLED: true, + IS_CALENDAR_ENABLED: true, + IS_SELF_BILLING_ENABLED: true, + }, + ); + + const objectMetadataRepository = + manager.getRepository(ObjectMetadataEntity); + const fieldMetadataRepository = + manager.getRepository(FieldMetadataEntity); + + /** + * Update all object metadata with standard id + */ + const updateObjectMetadataCollection: Partial[] = + []; + const updateFieldMetadataCollection: Partial[] = []; + const originalObjectMetadataCollection = + await objectMetadataRepository.find({ + where: { + fields: { isCustom: false }, + }, + relations: ['fields'], + }); + const customObjectMetadataCollection = + originalObjectMetadataCollection.filter( + (metadata) => metadata.isCustom, + ); + const standardObjectMetadataMap = new Map( + standardObjectMetadataCollection.map((metadata) => [ + metadata.nameSingular, + metadata, + ]), + ); + + for (const originalObjectMetadata of originalObjectMetadataCollection) { + const standardObjectMetadata = standardObjectMetadataMap.get( + originalObjectMetadata.nameSingular, + ); + + if (!standardObjectMetadata && !originalObjectMetadata.isCustom) { + continue; + } + + const computedStandardObjectMetadata = computeStandardObject( + !standardObjectMetadata + ? { + ...originalObjectMetadata, + fields: standardFieldMetadataCollection, + } + : standardObjectMetadata, + originalObjectMetadata, + customObjectMetadataCollection, + ); + + if ( + !originalObjectMetadata.isCustom && + !originalObjectMetadata.standardId + ) { + updateObjectMetadataCollection.push({ + id: originalObjectMetadata.id, + standardId: computedStandardObjectMetadata.standardId, + }); + } + + for (const fieldMetadata of originalObjectMetadata.fields) { + const standardFieldMetadata = + computedStandardObjectMetadata.fields.find( + (field) => field.name === fieldMetadata.name, + ); + + if (!standardFieldMetadata || standardFieldMetadata.isCustom) { + continue; + } + + updateFieldMetadataCollection.push({ + id: fieldMetadata.id, + standardId: standardFieldMetadata.standardId, + }); + } + } + + await objectMetadataRepository.save(updateObjectMetadataCollection); + + await fieldMetadataRepository.save(updateFieldMetadataCollection); + + await queryRunner.commitTransaction(); + } catch (error) { + await queryRunner.rollbackTransaction(); + this.logger.error('Error adding standard id to metadata', error); + } finally { + await queryRunner.release(); + } + } +} diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module.ts index a2c5024936cff..36371970d061c 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/commands/workspace-sync-metadata-commands.module.ts @@ -4,6 +4,7 @@ import { DataSourceModule } from 'src/metadata/data-source/data-source.module'; import { WorkspaceSyncMetadataModule } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.module'; import { WorkspaceHealthModule } from 'src/workspace/workspace-health/workspace-health.module'; import { WorkspaceModule } from 'src/core/workspace/workspace.module'; +import { AddStandardIdCommand } from 'src/workspace/workspace-sync-metadata/commands/add-standard-id.command'; import { SyncWorkspaceMetadataCommand } from './sync-workspace-metadata.command'; @@ -16,6 +17,10 @@ import { SyncWorkspaceLoggerService } from './services/sync-workspace-logger.ser WorkspaceModule, DataSourceModule, ], - providers: [SyncWorkspaceMetadataCommand, SyncWorkspaceLoggerService], + providers: [ + SyncWorkspaceMetadataCommand, + AddStandardIdCommand, + SyncWorkspaceLoggerService, + ], }) export class WorkspaceSyncMetadataCommandsModule {} diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/comparators/workspace-field.comparator.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/comparators/workspace-field.comparator.ts index 86842970956ca..2b8e93a8c2cdd 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/comparators/workspace-field.comparator.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/comparators/workspace-field.comparator.ts @@ -11,7 +11,10 @@ import { ComputedPartialObjectMetadata } from 'src/workspace/workspace-sync-meta import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity'; import { transformMetadataForComparison } from 'src/workspace/workspace-sync-metadata/comparators/utils/transform-metadata-for-comparison.util'; -import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity'; +import { + FieldMetadataEntity, + FieldMetadataType, +} from 'src/metadata/field-metadata/field-metadata.entity'; const commonFieldPropertiesToIgnore = [ 'id', @@ -61,7 +64,8 @@ export class WorkspaceFieldComparator { }, propertiesToStringify: fieldPropertiesToStringify, keyFactory(datum) { - return datum.name; + // Happen when the field is custom + return datum.standardId || datum.name; }, }, ); @@ -85,7 +89,8 @@ export class WorkspaceFieldComparator { }, propertiesToStringify: fieldPropertiesToStringify, keyFactory(datum) { - return datum.name; + // Happen when the field is custom + return datum.standardId || datum.name; }, }, ); @@ -98,13 +103,20 @@ export class WorkspaceFieldComparator { for (const difference of fieldMetadataDifference) { const fieldName = difference.path[0]; + const findField = ( + field: ComputedPartialFieldMetadata | FieldMetadataEntity, + ) => { + if (field.isCustom) { + return field.name === fieldName; + } + + return field.standardId === fieldName; + }; // Object shouldn't have thousands of fields, so we can use find here - const standardFieldMetadata = standardObjectMetadata.fields.find( - (field) => field.name === fieldName, - ); - const originalFieldMetadata = originalObjectMetadata.fields.find( - (field) => field.name === fieldName, - ); + const standardFieldMetadata = + standardObjectMetadata.fields.find(findField); + const originalFieldMetadata = + originalObjectMetadata.fields.find(findField); switch (difference.type) { case 'CREATE': { diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/constants/standard-field-ids.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/constants/standard-field-ids.ts index 46abcaa775e8d..8dd796af95fbf 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/constants/standard-field-ids.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/constants/standard-field-ids.ts @@ -6,278 +6,279 @@ */ export const activityTargetStandardFieldIds = { - activity: '20202020-c7fc-4d02-88c8-edbd6e7a22fc', - person: '20202020-be11-44ff-b7ea-21b9ac955340', - company: '20202020-cf30-47e2-94d6-084a96b93a64', - opportunity: '20202020-80d4-4510-9afc-b1c7242b0606', - custom: '20202020-402d-4a7f-b541-2815edd7abc7', + activity: '20202020-ca58-478c-a4f5-ae825671c30e', + person: '20202020-4afd-4ae7-99c2-de57d795a93f', + company: '20202020-7cc0-44a1-8068-f11171fdd02e', + opportunity: '20202020-1fc2-4af1-8c91-7901ee0fd38b', + custom: '20202020-7f21-442f-94be-32462281b1ca', }; export const activityStandardFieldIds = { - title: '20202020-a1b2-4c3d-88e8-edf6e7a8b9fc', - body: '20202020-c2b3-4d4e-88f9-edg7h8i9j0kc', - type: '20202020-d3c4-4e5f-89g0-feh1i2j3k4ld', - reminderAt: '20202020-e4d5-5f6g-9a1b-gfi2j3k4l5me', - dueAt: '20202020-f5e6-6g7h-0b2c-hgj3k4l5m6nf', - completedAt: '20202020-g6f7-7h8i-1c3d-ihk4l5m6n7og', - activityTargets: '20202020-h7g8-8i9j-2d4e-jil5m6n7o8pq', - attachments: '20202020-i8h9-9j0a-3e5f-kjm6n7o8p9qr', - comments: '20202020-j9i0-0a1b-4f6g-lkn7o8p9q0rs', - author: '20202020-k0j1-1b2c-5g7h-mlo8p9q1r2st', - assignee: '20202020-l1k2-2c3d-6h8i-nmp9q0r1s2tu', + title: '20202020-24a1-4d94-a071-617f3eeed7b0', + body: '20202020-209b-440a-b2a8-043fa36a7d37', + type: '20202020-0f2b-4aab-8827-ee5d3f07d993', + reminderAt: '20202020-eb06-43e2-ba06-336be0e665a3', + dueAt: '20202020-0336-4511-ba79-565b12801bd9', + completedAt: '20202020-0f4d-4fca-9f2f-6309d9ecb85f', + activityTargets: '20202020-7253-42cb-8586-8cf950e70b79', + attachments: '20202020-5547-4197-bc2e-a07dfc4559ca', + comments: '20202020-6b2e-4d29-bbd1-ecddb330e71a', + author: '20202020-455f-44f2-8e89-1b0ef01cb7fb', + assignee: '20202020-4259-48e4-9e77-6b92991906d5', }; export const apiKeyStandardFieldIds = { - name: '20202020-a1c3-4e5f-88g9-edh6i7j8k9lm', - expiresAt: '20202020-b2d4-5f6g-99h0-fei1j2k3l4mn', - revokedAt: '20202020-c3e5-6g7h-0a1b-gfj2k3l4m5no', + name: '20202020-72e6-4079-815b-436ce8a62f23', + expiresAt: '20202020-659b-4241-af59-66515b8e7d40', + revokedAt: '20202020-06ab-44b5-8faf-f6e407685001', }; export const attachmentStandardFieldIds = { - name: '20202020-d4f6-7h8j-91k2-lm3n4o5p6q7r', - fullPath: '20202020-e5g7-8i9k-02l3-mn4p5q6r7s8t', - type: '20202020-f6h8-9j0l-13m4-on5p6q7r8s9u', - author: '20202020-g7i9-0k1m-24n5-po6q7r8s9t0v', - activity: '20202020-h8j0-1l2n-35o6-qp7r8s9t1u2w', - person: '20202020-i9k1-2m3o-46p7-qr8s9t0u3v4x', - company: '20202020-j0l2-3n4p-57q8-rs9t1u4v5w6y', - opportunity: '20202020-k1m3-4o5q-68r9-st0u2v5w6x7z', + name: '20202020-87a5-48f8-bbf7-ade388825a57', + fullPath: '20202020-0d19-453d-8e8d-fbcda8ca3747', + type: '20202020-a417-49b8-a40b-f6a7874caa0d', + author: '20202020-6501-4ac5-a4ef-b2f8522ef6cd', + activity: '20202020-b569-481b-a13f-9b94e47e54fe', + person: '20202020-0158-4aa2-965c-5cdafe21ffa2', + company: '20202020-ceab-4a28-b546-73b06b4c08d5', + opportunity: '20202020-7374-499d-bea3-9354890755b5', + custom: '20202020-302d-43b3-9aea-aa4f89282a9f', }; export const baseObjectStandardFieldIds = { - id: '20202020-l2m4-5n6o-78p9-qrst0u1v2w3x', - createdAt: '20202020-m3n5-6o7p-89q0-rstu1v2w3x4y', - updatedAt: '20202020-n4o6-7p8q-90r1-stuv2w3x4y5z', + id: '20202020-eda0-4cee-9577-3eb357e3c22b', + createdAt: '20202020-66ac-4502-9975-e4d959c50311', + updatedAt: '20202020-d767-4622-bdcf-d8a084834d86', }; export const blocklistStandardFieldIds = { - handle: '20202020-o5p7-8q9r-01s2-tuv3w4x5y6z7', - workspaceMember: '20202020-p6q8-9r0s-12t3-uvw4x5y6z7a8', + handle: '20202020-eef3-44ed-aa32-4641d7fd4a3e', + workspaceMember: '20202020-548d-4084-a947-fa20a39f7c06', }; export const calendarChannelStandardFieldIds = { - connectedAccount: '20202020-q7r9-0s1t-23u4-vwx5y6z7a8b9', - handle: '20202020-r8s0-1t2u-34v5-wxy6z7a8b9c0', - visibility: '20202020-s9t1-2u3v-45w6-xyz7a8b9c0d1', - isContactAutoCreationEnabled: '20202020-t0u2-3v4w-56x7-yza8b9c0d1e2', - isSyncEnabled: '20202020-u1v3-4w5x-67y8-zab9c0d1e2f3', - syncCursor: '20202020-v2w4-5x6y-78z9-abc0d1e2f3g4', + connectedAccount: '20202020-95b1-4f44-82dc-61b042ae2414', + handle: '20202020-1d08-420a-9aa7-22e0f298232d', + visibility: '20202020-1b07-4796-9f01-d626bab7ca4d', + isContactAutoCreationEnabled: '20202020-50fb-404b-ba28-369911a3793a', + isSyncEnabled: '20202020-fe19-4818-8854-21f7b1b43395', + syncCursor: '20202020-bac2-4852-a5cb-7a7898992b70', }; export const calendarEventAttendeeStandardFieldIds = { - calendarEvent: '20202020-w3x5-6y7z-89a0-bcd1e2f3g4h5', - handle: '20202020-x4y6-7z8a-90b1-cde2f3g4h5i6', - displayName: '20202020-y5z7-8a9b-01c2-def3g4h5i6j7', - isOrganizer: '20202020-z6a8-9b0c-12d3-efg4h5i6j7k8', - responseStatus: '20202020-a7b9-0c1d-23e4-fgh5i6j7k8l9', - person: '20202020-b8c0-1d2e-34f5-ghi6j7k8l9m0', - workspaceMember: '20202020-c9d1-2e3f-45g6-hij7k8l9m0n1', + calendarEvent: '20202020-fe3a-401c-b889-af4f4657a861', + handle: '20202020-8692-4580-8210-9e09cbd031a7', + displayName: '20202020-ee1e-4f9f-8ac1-5c0b2f69691e', + isOrganizer: '20202020-66e7-4e00-9e06-d06c92650580', + responseStatus: '20202020-cec0-4be8-8fba-c366abc23147', + person: '20202020-5761-4842-8186-e1898ef93966', + workspaceMember: '20202020-20e4-4591-93ed-aeb17a4dcbd2', }; export const calendarEventStandardFieldIds = { - title: '20202020-d0e1-2f3g-4h5i-6j7k8l9m0n1o', - isCanceled: '20202020-e1f2-3g4h-5i6j-7k8l9m0n2p', - isFullDay: '20202020-f2g3-4h5i-6j7k-8l9m0n1o2p3', - startsAt: '20202020-g3h4-5i6j-7k8l-9m0n1o2p3q4', - endsAt: '20202020-h4i5-6j7k-8l9m-0n1o2p3q4r5', - externalCreatedAt: '20202020-i5j6-7k8l-9m0n-1o2p3q4r5s6', - externalUpdatedAt: '20202020-j6k7-8l9m-0n1o-2p3q4r5s6t7', - description: '20202020-k7l8-9m0n-1o2p-3q4r5s6t7u8', - location: '20202020-l8m9-0n1o-2p3q-4r5s6t7u8v9', - iCalUID: '20202020-m9n0-1o2p-3q4r-5s6t7u8v9w0', - conferenceSolution: '20202020-n0o1-2p3q-4r5s-6t7u8v9w0x1', - conferenceUri: '20202020-o1p2-3q4r-5s6t-7u8v9w0x1y2', - recurringEventExternalId: '20202020-p2q3-4r5s-6t7u-8v9w0x1y2z3', - eventAttendees: '20202020-q3r4-5s6t-7u8v-9w0x1y2z3a4', + title: '20202020-080e-49d1-b21d-9702a7e2525c', + isCanceled: '20202020-335b-4e04-b470-43b84b64863c', + isFullDay: '20202020-551c-402c-bb6d-dfe9efe86bcb', + startsAt: '20202020-2c57-4c75-93c5-2ac950a6ed67', + endsAt: '20202020-2554-4ee1-a617-17907f6bab21', + externalCreatedAt: '20202020-9f03-4058-a898-346c62181599', + externalUpdatedAt: '20202020-b355-4c18-8825-ef42c8a5a755', + description: '20202020-52c4-4266-a98f-e90af0b4d271', + location: '20202020-641a-4ffe-960d-c3c186d95b17', + iCalUID: '20202020-f24b-45f4-b6a3-d2f9fcb98714', + conferenceSolution: '20202020-1c3f-4b5a-b526-5411a82179eb', + conferenceUri: '20202020-0fc5-490a-871a-2df8a45ab46c', + recurringEventExternalId: '20202020-4b96-43d0-8156-4c7a9717635c', + eventAttendees: '20202020-e07e-4ccb-88f5-6f3d00458eec', }; export const commentStandardFieldIds = { - body: '20202020-r2s3-4t5u-6v7w-8x9y0z1a2b3c', - author: '20202020-s3t4-5u6v-7w8x-9y0z1a2b3c4d', - activity: '20202020-t4u5-6v7w-8x9y-0z1a2b3c4d5e', + body: '20202020-d5eb-49d2-b3e0-1ed04145ebb7', + author: '20202020-2ab1-427e-a981-cf089de3a9bd', + activity: '20202020-c8d9-4c30-a35e-dc7f44388070', }; export const companyStandardFieldIds = { - name: '20202020-u2v3-4w5x-6y7z-8a9b0c1d2e3f', - domainName: '20202020-v3w4-5x6y-7z8a-9b0c1d2e3g4h', - address: '20202020-w4x5-6y7z-8a9b-0c1d2e3f4g5h', - employees: '20202020-x5y6-7z8a-9b0c-1d2e3f4g5h6i', - linkedinLink: '20202020-y6z7-8a9b-0c1d-2e3f4g5h6i7j', - xLink: '20202020-z7a8-9b0c-1d2e-3f4g5h6i7j8k', - annualRecurringRevenue: '20202020-a8b9-0c1d-2e3f-4g5h6i7j8k9l', - idealCustomerProfile: '20202020-b9c0-1d2e-3f4g-5h6i7j8k9l0m', - position: '20202020-c0d1-2e3f-4g5h-6i7j8k9l0m1n', - people: '20202020-d1e2-3f4g-5h6i-7j8k9l0m1n2o', - accountOwner: '20202020-e2f3-4g5h-6i7j-8k9l0m1n2o3p', - activityTargets: '20202020-f3g4-5h6i-7j8k-9l0m1n2o3p4q', - opportunities: '20202020-g4h5-6i7j-8k9l-0m1n2o3p4q5r', - favorites: '20202020-h5i6-7j8k-9l0m-1n2o3p4q5r6s', - attachments: '20202020-i6j7-8k9l-0m1n-2o3p4q5r6s7t', + name: '20202020-4d99-4e2e-a84c-4a27837b1ece', + domainName: '20202020-0c28-43d8-8ba5-3659924d3489', + address: '20202020-a82a-4ee2-96cc-a18a3259d953', + employees: '20202020-8965-464a-8a75-74bafc152a0b', + linkedinLink: '20202020-ebeb-4beb-b9ad-6848036fb451', + xLink: '20202020-6f64-4fd9-9580-9c1991c7d8c3', + annualRecurringRevenue: '20202020-602a-495c-9776-f5d5b11d227b', + idealCustomerProfile: '20202020-ba6b-438a-8213-2c5ba28d76a2', + position: '20202020-9b4e-462b-991d-a0ee33326454', + people: '20202020-3213-4ddf-9494-6422bcff8d7c', + accountOwner: '20202020-95b8-4e10-9881-edb5d4765f9d', + activityTargets: '20202020-c2a5-4c9b-9d9a-582bcd57fbc8', + opportunities: '20202020-add3-4658-8e23-d70dccb6d0ec', + favorites: '20202020-4d1d-41ac-b13b-621631298d55', + attachments: '20202020-c1b5-4120-b0f0-987ca401ed53', }; export const connectedAccountStandardFieldIds = { - handle: '20202020-j7k8-9l0m-1n2o-3p4q5r6s7t8u', - provider: '20202020-k8l9-0m1n-2o3p-4q5r6s7t8u9v', - accessToken: '20202020-l9m0-1n2o-3p4q-5r6s7t8u9v0w', - refreshToken: '20202020-m0n1-2o3p-4q5r-6s7t8u9v0w1x', - accountOwner: '20202020-n1o2-3p4q-5r6s-7t8u9v0w1x2y', - lastSyncHistoryId: '20202020-o2p3-4q5r-6s7t-8u9v0w1x2y3z', - messageChannels: '20202020-p3q4-5r6s-7t8u-9v0w1x2y3z4a', - calendarChannels: '20202020-q4r5-6s7t-8u9v-0w1x2y3z4a5b', + handle: '20202020-c804-4a50-bb05-b3a9e24f1dec', + provider: '20202020-ebb0-4516-befc-a9e95935efd5', + accessToken: '20202020-707b-4a0a-8753-2ad42efe1e29', + refreshToken: '20202020-532d-48bd-80a5-c4be6e7f6e49', + accountOwner: '20202020-3517-4896-afac-b1d0aa362af6', + lastSyncHistoryId: '20202020-115c-4a87-b50f-ac4367a971b9', + messageChannels: '20202020-24f7-4362-8468-042204d1e445', + calendarChannels: '20202020-af4a-47bb-99ec-51911c1d3977', }; export const favoriteStandardFieldIds = { - position: '20202020-j7k8-9l0m-1n2o-3p4q5r6s7t8u', - workspaceMember: '20202020-k8l9-0m1n-2o3p-4q5r6s7t8u9v', - person: '20202020-l9m0-1n2o-3p4q-5r6s7t8u9v0w', - company: '20202020-m0n1-2o3p-4q5r-6s7t8u9v0w1x', - opportunity: '20202020-n1o2-3p4q-5r6s-7t8u9v0w1x2y', - custom: '20202020-o2p3-4q5r-6s7t-8u9v0w1x2y3z', + position: '20202020-dd26-42c6-8c3c-2a7598c204f6', + workspaceMember: '20202020-ce63-49cb-9676-fdc0c45892cd', + person: '20202020-c428-4f40-b6f3-86091511c41c', + company: '20202020-cff5-4682-8bf9-069169e08279', + opportunity: '20202020-dabc-48e1-8318-2781a2b32aa2', + custom: '20202020-855a-4bc8-9861-79deef37011f', }; export const messageChannelMessageAssociationStandardFieldIds = { - messageChannel: '20202020-p2q3-4r5s-6t7u-8v9w0x1y2z3a', - message: '20202020-q3r4-5s6t-7u8v-9w0x1y2z3a4b5', - messageExternalId: '20202020-r4s5-6t7u-8v9w-0x1y2z3a4b5c6', - messageThread: '20202020-s5t6-7u8v-9w0x-1y2z3a4b5c6d7', - messageThreadExternalId: '20202020-t6u7-8v9w-0x1y-2z3a4b5c6d7e8', + messageChannel: '20202020-b658-408f-bd46-3bd2d15d7e52', + message: '20202020-da5d-4ac5-8743-342ab0a0336b', + messageExternalId: '20202020-37d6-438f-b6fd-6503596c8f34', + messageThread: '20202020-fac8-42a8-94dd-44dbc920ae16', + messageThreadExternalId: '20202020-35fb-421e-afa0-0b8e8f7f9018', }; export const messageChannelStandardFieldIds = { - visibility: '20202020-u7v8-9w0x-1y2z-3a4b5c6d7e8f9', - handle: '20202020-v8w9-0x1y-2z3a-4b5c6d7e8f9g0', - connectedAccount: '20202020-w9x0-1y2z-3a4b-5c6d7e8f9g0h1', - type: '20202020-x0y1-2z3a-4b5c-6d7e8f9g0h1i2', - isContactAutoCreationEnabled: '20202020-y1z2-3a4b-5c6d-7e8f9g0h1i2j3', - messageChannelMessageAssociations: '20202020-z2a3-4b5c-6d7e-8f9g0h1i2j3k4', + visibility: '20202020-6a6b-4532-9767-cbc61b469453', + handle: '20202020-2c96-43c3-93e3-ed6b1acb69bc', + connectedAccount: '20202020-49a2-44a4-b470-282c0440d15d', + type: '20202020-ae95-42d9-a3f1-797a2ea22122', + isContactAutoCreationEnabled: '20202020-fabd-4f14-b7c6-3310f6d132c6', + messageChannelMessageAssociations: '20202020-49b8-4766-88fd-75f1e21b3d5f', }; export const messageParticipantStandardFieldIds = { - message: '20202020-a3b4-5c6d-7e8f-9g0h1i2j3k4l5', - role: '20202020-b4c5-6d7e-8f9g-0h1i2j3k4l5m6n', - handle: '20202020-c5d6-7e8f-9g0h-1i2j3k4l5m6n7o', - displayName: '20202020-d6e7-8f9g-0h1i-2j3k4l5m6n7o8', - person: '20202020-e7f8-9g0h-1i2j-3k4l5m6n7o8p9', - workspaceMember: '20202020-f8g9-0h1i-2j3k-4l5m6n7o8p9q', + message: '20202020-985b-429a-9db9-9e55f4898a2a', + role: '20202020-65d1-42f4-8729-c9ec1f52aecd', + handle: '20202020-2456-464e-b422-b965a4db4a0b', + displayName: '20202020-36dd-4a4f-ac02-228425be9fac', + person: '20202020-249d-4e0f-82cd-1b9df5cd3da2', + workspaceMember: '20202020-77a7-4845-99ed-1bcbb478be6f', }; export const messageThreadStandardFieldIds = { - messages: '20202020-g9h0-1i2j-3k4l-5m6n7o8p9q0r1', - messageChannelMessageAssociations: '20202020-h0i1-2j3k-4l5m-6n7o8p9q0r1s2t3', + messages: '20202020-3115-404f-aade-e1154b28e35a', + messageChannelMessageAssociations: '20202020-314e-40a4-906d-a5d5d6c285f6', }; export const messageStandardFieldIds = { - headerMessageId: '20202020-i1j2-3k4l-5m6n-7o8p9q0r1s2', - messageThread: '20202020-j2k3-4l5m-6n7o-8p9q0r1s2t3u', - direction: '20202020-k3l4-5m6n-7o8p-9q0r1s2t3u4v', - subject: '20202020-l4m5-6n7o-8p9q-0r1s2t3u4v5w', - text: '20202020-m5n6-7o8p-9q0r-1s2t3u4v5w6x', - receivedAt: '20202020-n6o7-8p9q-0r1s-2t3u4v5w6x7y', - messageParticipants: '20202020-o7p8-9q0r-1s2t-3u4v5w6x7y8z', - messageChannelMessageAssociations: '20202020-p8q9-0r1s-2t3u-4v5w6x7y8z9a', + headerMessageId: '20202020-72b5-416d-aed8-b55609067d01', + messageThread: '20202020-30f2-4ccd-9f5c-e41bb9d26214', + direction: '20202020-0203-4118-8e2a-05b9bdae6dab', + subject: '20202020-52d1-4036-b9ae-84bd722bb37a', + text: '20202020-d2ee-4e7e-89de-9a0a9044a143', + receivedAt: '20202020-140a-4a2a-9f86-f13b6a979afc', + messageParticipants: '20202020-7cff-4a74-b63c-73228448cbd9', + messageChannelMessageAssociations: '20202020-3cef-43a3-82c6-50e7cfbc9ae4', }; export const opportunityStandardFieldIds = { - name: '20202020-q8r9-0s1t-2u3v-4w5x6y7z8a9b0', - amount: '20202020-r9s0-1t2u-3v4w-5x6y7z8a9b0c1', - closeDate: '20202020-s0t1-2u3v-4w5x-6y7z8a9b0c1d2', - probability: '20202020-t1u2-3v4w-5x6y-7z8a9b0c1d2e3', - stage: '20202020-u2v3-4w5x-6y7z-8a9b0c1d2e3f4', - position: '20202020-v3w4-5x6y-7z8a-9b0c1d2e3f4g5', - pipelineStep: '20202020-w4x5-6y7z-8a9b-0c1d2e3f4g5h6', - pointOfContact: '20202020-x5y6-7z8a-9b0c-1d2e3f4g5h6i7', - company: '20202020-y6z7-8a9b-0c1d-2e3f4g5h6i7j8', - favorites: '20202020-z7a8-9b0c-1d2e-3f4g5h6i7j8k9', - activityTargets: '20202020-a8b9-0c1d-2e3f-4g5h6i7j8k9l0', - attachments: '20202020-b9c0-1d2e-3f4g-5h6i7j8k9l0m1', + name: '20202020-8609-4f65-a2d9-44009eb422b5', + amount: '20202020-583e-4642-8533-db761d5fa82f', + closeDate: '20202020-527e-44d6-b1ac-c4158d307b97', + probability: '20202020-69d4-45f3-9703-690b09fafcf0', + stage: '20202020-6f76-477d-8551-28cd65b2b4b9', + position: '20202020-806d-493a-bbc6-6313e62958e2', + pipelineStep: '20202020-cc8c-4ae7-8d83-25c3addaec5a', + pointOfContact: '20202020-8dfb-42fc-92b6-01afb759ed16', + company: '20202020-cbac-457e-b565-adece5fc815f', + favorites: '20202020-a1c2-4500-aaae-83ba8a0e827a', + activityTargets: '20202020-220a-42d6-8261-b2102d6eab35', + attachments: '20202020-87c7-4118-83d6-2f4031005209', }; export const personStandardFieldIds = { - name: '20202020-q9r0-1s2t-3u4v-5w6x7y8z9a0b', - email: '20202020-r0s1-2t3u-4v5w-6x7y8z9a0b1c', - linkedinLink: '20202020-s1t2-3u4v-5w6x-7y8z9a0b1c2d', - xLink: '20202020-t2u3-4v5w-6x7y-8z9a0b1c2d3e', - jobTitle: '20202020-u3v4-5w6x-7y8z-9a0b1c2d3e4f', - phone: '20202020-v4w5-6x7y-8z9a-0b1c2d3e4f5g', - city: '20202020-w5x6-7y8z-9a0b-1c2d3e4f5g6h', - avatarUrl: '20202020-x6y7-8z9a-0b1c-2d3e4f5g6h7i', - position: '20202020-y7z8-9a0b-1c2d-3e4f5g6h7i8j', - company: '20202020-z8a9-0b1c-2d3e-4f5g6h7i8j9k', - pointOfContactForOpportunities: '20202020-a9b0-1c2d-3e4f-5g6h7i8j9k0l', - activityTargets: '20202020-b0c1-2d3e-4f5g-6h7i8j9k0l1m', - favorites: '20202020-c1d2-3e4f-5g6h-7i8j9k0l1m2n', - attachments: '20202020-d2e3-4f5g-6h7i-8j9k0l1m2n3o', - messageParticipants: '20202020-e3f4-5g6h-7i8j-9k0l1m2n3o4p', - calendarEventAttendees: '20202020-f4g5-6h7i-8j9k-0l1m2n3o4p5q', + name: '20202020-3875-44d5-8c33-a6239011cab8', + email: '20202020-a740-42bb-8849-8980fb3f12e1', + linkedinLink: '20202020-f1af-48f7-893b-2007a73dd508', + xLink: '20202020-8fc2-487c-b84a-55a99b145cfd', + jobTitle: '20202020-b0d0-415a-bef9-640a26dacd9b', + phone: '20202020-4564-4b8b-a09f-05445f2e0bce', + city: '20202020-5243-4ffb-afc5-2c675da41346', + avatarUrl: '20202020-b8a6-40df-961c-373dc5d2ec21', + position: '20202020-fcd5-4231-aff5-fff583eaa0b1', + company: '20202020-e2f3-448e-b34c-2d625f0025fd', + pointOfContactForOpportunities: '20202020-911b-4a7d-b67b-918aa9a5b33a', + activityTargets: '20202020-dee7-4b7f-b50a-1f50bd3be452', + favorites: '20202020-4073-4117-9cf1-203bcdc91cbd', + attachments: '20202020-cd97-451f-87fa-bcb789bdbf3a', + messageParticipants: '20202020-498e-4c61-8158-fa04f0638334', + calendarEventAttendees: '20202020-52ee-45e9-a702-b64b3753e3a9', }; export const pipelineStepStandardFieldIds = { - name: '20202020-g5h6-7i8j-9k0l-1m2n3o4p5q6r', - color: '20202020-h6i7-8j9k-0l1m-2n3o4p5q6r7s', - position: '20202020-i7j8-9k0l-1m2n-3o4p5q6r7s8t', - opportunities: '20202020-j8k9-0l1m-2n3o-4p5q6r7s8t9u', + name: '20202020-e10a-4119-9466-97873e86fa47', + color: '20202020-4a09-4088-90b8-ce1c72730f43', + position: '20202020-44e8-4520-af64-4a3cb37fa0c5', + opportunities: '20202020-0442-482a-867f-6d8fd4145ed1', }; export const viewFieldStandardFieldIds = { - fieldMetadataId: '20202020-k9l0-1m2n-3o4p-5q6r7s8t9u0v', - isVisible: '20202020-l0m1-2n3o-4p5q-6r7s8t9u0v1w', - size: '20202020-m1n2-3o4p-5q6r-7s8t9u0v1w2x', - position: '20202020-n2o3-4p5q-6r7s-8t9u0v1w2x3y', - view: '20202020-o3p4-5q6r-7s8t-9u0v1w2x3y4z', + fieldMetadataId: '20202020-135f-4c5b-b361-15f24870473c', + isVisible: '20202020-e966-473c-9c18-f00d3347e0ba', + size: '20202020-6fab-4bd0-ae72-20f3ee39d581', + position: '20202020-19e5-4e4c-8c15-3a96d1fd0650', + view: '20202020-e8da-4521-afab-d6d231f9fa18', }; export const viewFilterStandardFieldIds = { - fieldMetadataId: '20202020-p4q5-6r7s-8t9u-0v1w2x3y4z5', - operand: '20202020-q5r6-7s8t-9u0v-1w2x3y4z5a6b', - value: '20202020-r6s7-8t9u-0v1w-2x3y4z5a6b7c', - displayValue: '20202020-s7t8-9u0v-1w2x-3y4z5a6b7c8d', - view: '20202020-t8u9-0v1w-2x3y-4z5a6b7c8d9e', + fieldMetadataId: '20202020-c9aa-4c94-8d0e-9592f5008fb0', + operand: '20202020-bd23-48c4-9fab-29d1ffb80310', + value: '20202020-1e55-4a1e-a1d2-fefb86a5fce5', + displayValue: '20202020-1270-4ebf-9018-c0ec10d5038e', + view: '20202020-4f5b-487e-829c-3d881c163611', }; export const viewSortStandardFieldIds = { - fieldMetadataId: '20202020-u4v5-6w7x-8y9z-0a1b2c3d4e5f', - direction: '20202020-v5w6-7x8y-9z0a-1b2c3d4e5f6g', - view: '20202020-w6x7-8y9z-0a1b-2c3d4e5f6g7h', + fieldMetadataId: '20202020-8240-4657-aee4-7f0df8e94eca', + direction: '20202020-b06e-4eb3-9b58-0a62e5d79836', + view: '20202020-bd6c-422b-9167-5c105f2d02c8', }; export const viewStandardFieldIds = { - name: '20202020-x7y8-9z0a-1b2c-3d4e5f6g7h8i', - objectMetadataId: '20202020-y8z9-0a1b-2c3d-4e5f6g7h8i9j', - type: '20202020-z9a0-1b2c-3d4e-5f6g7h8i9j0k', - isCompact: '20202020-a9b0-1c2d-3e4f-5g6h7i8j9k0l', - viewFields: '20202020-b0c1-2d3e-4f5g-6h7i8j9k0l1m', - viewFilters: '20202020-c1d2-3e4f-5g6h-7i8j9k0l1m2n', - viewSorts: '20202020-d2e3-4f5g-6h7i-8j9k0l1m2n3o', + name: '20202020-12c6-4f37-b588-c9b9bf57328d', + objectMetadataId: '20202020-d6de-4fd5-84dd-47f9e730368b', + type: '20202020-dd11-4607-9ec7-c57217262a7f', + isCompact: '20202020-674e-4314-994d-05754ea7b22b', + viewFields: '20202020-542b-4bdc-b177-b63175d48edf', + viewFilters: '20202020-ff23-4154-b63c-21fb36cd0967', + viewSorts: '20202020-891b-45c3-9fe1-80a75b4aa043', }; export const webhookStandardFieldIds = { - targetUrl: '20202020-u5v6-7w8x-9y0z-a1b2c3d4e5f6g', - operation: '20202020-v6w7-8x9y-0z1a-2b3c4d5e6f7h', + targetUrl: '20202020-1229-45a8-8cf4-85c9172aae12', + operation: '20202020-15b7-458e-bf30-74770a54410c', }; export const workspaceMemberStandardFieldIds = { - name: '20202020-w7x8-9y0z-a1b2-3c4d5e6f7g8h9', - colorScheme: '20202020-x8y9-0z1a-b2c3-4d5e6f7g8h9i', - locale: '20202020-y9z0-1a2b-c3d4-5e6f7g8h9i0j', - avatarUrl: '20202020-z0a1-2b3c-d4e5-6f7g8h9i0j1k', - userEmail: '20202020-a1b2-3c4d-e5f6-7g8h9i0j1k2l', - userId: '20202020-b2c3-4d5e-f6g7-8h9i0j1k2l3m', - authoredActivities: '20202020-c3d4-5e6f-g7h8-9i0j1k2l3m4n', - assignedActivities: '20202020-d4e5-6f7g-h8i9-0j1k2l3m4n5o', - favorites: '20202020-e5f6-7g8h-i9j0-k1l2m3n4o5p6', - accountOwnerForCompanies: '20202020-f6g7-8h9i-j0k1-l2m3n4o5p6q7', - authoredAttachments: '20202020-g7h8-9i0j-k1l2-m3n4o5p6q7r8', - authoredComments: '20202020-h8i9-0j1k-l2m3-n4o5p6q7r8s9', - connectedAccounts: '20202020-i9j0-1k2l-m3n4-o5p6q7r8s9t0', - messageParticipants: '20202020-j0k1-2l3m-n4o5-p6q7r8s9t0u1', - blocklist: '20202020-k1l2-3m4n-o5p6-q7r8s9t0u1v2', - calendarEventAttendees: '20202020-l2m3-4n5o-p6q7-r8s9t0u1v2w3', + name: '20202020-e914-43a6-9c26-3603c59065f4', + colorScheme: '20202020-66bc-47f2-adac-f2ef7c598b63', + locale: '20202020-402e-4695-b169-794fa015afbe', + avatarUrl: '20202020-0ced-4c4f-a376-c98a966af3f6', + userEmail: '20202020-4c5f-4e09-bebc-9e624e21ecf4', + userId: '20202020-75a9-4dfc-bf25-2e4b43e89820', + authoredActivities: '20202020-f139-4f13-a82f-a65a8d290a74', + assignedActivities: '20202020-5c97-42b6-8ca9-c07622cbb33f', + favorites: '20202020-f3c1-4faf-b343-cf7681038757', + accountOwnerForCompanies: '20202020-dc29-4bd4-a3c1-29eafa324bee', + authoredAttachments: '20202020-000f-4947-917f-1b09851024fe', + authoredComments: '20202020-5536-4f59-b837-51c45ef43b05', + connectedAccounts: '20202020-e322-4bde-a525-727079b4a100', + messageParticipants: '20202020-8f99-48bc-a5eb-edd33dd54188', + blocklist: '20202020-6cb2-4161-9f29-a4b7f1283859', + calendarEventAttendees: '20202020-0dbc-4841-9ce1-3e793b5b3512', }; export const customObjectStandardFieldIds = { - name: '20202020-z9a0-1b2c-3d4e-5f6g7h8i9j0k1', - position: '20202020-a0b1-2c3d-4e5f-6g7h8i9j0k1l2', - activityTargets: '20202020-b1c2-3d4e-5f6g-7h8i9j0k1l2m3', - favorites: '20202020-c2d3-4e5f-6g7h-8i9j0k1l2m3n4', - attachments: '20202020-d3e4-5f6g-7h8i-9j0k1l2m3n4o5', + name: '20202020-ba07-4ffd-ba63-009491f5749c', + position: '20202020-c2bd-4e16-bb9a-c8b0411bf49d', + activityTargets: '20202020-7f42-40ae-b96c-c8a61acc83bf', + favorites: '20202020-a4a7-4686-b296-1c6c3482ee21', + attachments: '20202020-8d59-46ca-b7b2-73d167712134', }; diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/constants/standard-object-ids.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/constants/standard-object-ids.ts index b733fda0ec1dc..2dbf51e8d4e52 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/constants/standard-object-ids.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/constants/standard-object-ids.ts @@ -6,30 +6,30 @@ */ export const standardObjectIds = { - activityTarget: '20202020-3219-4be0-b153-064407ced641', - activity: '20202020-c7fc-4d02-88c8-edbd6e7a22fc', - apiKey: '20202020-be11-44ff-b7ea-21b9ac955340', - attachment: '20202020-cf30-47e2-94d6-084a96b93a64', - blocklist: '20202020-80d4-4510-9afc-b1c7242b0606', - calendarChannel: '20202020-402d-4a7f-b541-2815edd7abc7', - calendarEventAttendee: '20202020-5e3e-4e3e-8e3e-3e3e3e3e3e3e', - calendarEvent: '20202020-6e9f-4ff7-bd66-07c40f255c0e', - comment: '20202020-a625-4879-a2f8-7f933966b8b4', - company: '20202020-d5b7-446e-af6a-7c8aa0ab89af', - connectedAccount: '20202020-92a7-4bd2-a41a-8013ed35f8c4', - favorite: '20202020-980b-4a18-8d3c-4aff88704eb4', - messageChannelMessageAssociation: '20202020-f4c5-4c8d-88af-5224b4823b9e', - messageChannel: '20202020-810f-4063-bf40-0e9e400fa81e', - messageParticipant: '20202020-bedb-4636-b5a6-0ae383d0c9b4', - messageThread: '20202020-499d-4a4a-9d35-2ab6c0e63b3c', - message: '20202020-b8b3-4e7d-b993-e47c2625656b', - opportunity: '20202020-4f4b-49aa-b2ab-a131d7a829fb', - person: '20202020-8446-4930-97a7-e086d5560f4a', - pipelineStep: '20202020-4012-4b22-96ec-1527c8d6f609', - viewField: '20202020-576a-45f4-9e36-a503f9c254eb', - viewFilter: '20202020-b2cb-4dbb-a090-40d74b71766b', - viewSort: '20202020-4ecf-455c-8469-c16dda3d3836', - view: '20202020-8ac1-4c44-af31-369eae9a1668', - webhook: '20202020-4092-45b2-92c3-f37d1e7f8515', - workspaceMember: '20202020-06c1-4bd5-9d31-347ecbd3d46a', + activityTarget: '20202020-2945-440e-8d1a-f84672d33d5e', + activity: '20202020-39aa-4a89-843b-eb5f2a8b677f', + apiKey: '20202020-4c00-401d-8cda-ec6a4c41cd7d', + attachment: '20202020-bd3d-4c60-8dca-571c71d4447a', + blocklist: '20202020-0408-4f38-b8a8-4d5e3e26e24d', + calendarChannel: '20202020-e8f2-40e1-a39c-c0e0039c5034', + calendarEventAttendee: '20202020-a1c3-47a6-9732-27e5b1e8436d', + calendarEvent: '20202020-8f1d-4eef-9f85-0d1965e27221', + comment: '20202020-435f-4de9-89b5-97e32233bf5f', + company: '20202020-b374-4779-a561-80086cb2e17f', + connectedAccount: '20202020-977e-46b2-890b-c3002ddfd5c5', + favorite: '20202020-ab56-4e05-92a3-e2414a499860', + messageChannelMessageAssociation: '20202020-ad1e-4127-bccb-d83ae04d2ccb', + messageChannel: '20202020-fe8c-40bc-a681-b80b771449b7', + messageParticipant: '20202020-a433-4456-aa2d-fd9cb26b774a', + messageThread: '20202020-849a-4c3e-84f5-a25a7d802271', + message: '20202020-3f6b-4425-80ab-e468899ab4b2', + opportunity: '20202020-9549-49dd-b2b2-883999db8938', + person: '20202020-e674-48e5-a542-72570eee7213', + pipelineStep: '20202020-f9a3-45f3-82e2-28952a8b19bf', + viewField: '20202020-4d19-4655-95bf-b2a04cf206d4', + viewFilter: '20202020-6fb6-4631-aded-b7d67e952ec8', + viewSort: '20202020-e46a-47a8-939a-e5d911f83531', + view: '20202020-722e-4739-8e2c-0c372d661f49', + webhook: '20202020-be4d-4e08-811d-0fffcd13ffd4', + workspaceMember: '20202020-3319-4234-a34c-82d5c0e881a6', }; diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/decorators/field-metadata.decorator.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/decorators/field-metadata.decorator.ts index 39cdda2605da7..1d69b5d49178b 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/decorators/field-metadata.decorator.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/decorators/field-metadata.decorator.ts @@ -9,6 +9,7 @@ import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.en import { generateTargetColumnMap } from 'src/metadata/field-metadata/utils/generate-target-column-map.util'; import { generateDefaultValue } from 'src/metadata/field-metadata/utils/generate-default-value'; import { TypedReflect } from 'src/utils/typed-reflect'; +import { createDeterministicUuid } from 'src/workspace/workspace-sync-metadata/utils/create-deterministic-uuid.util'; export function FieldMetadata( params: FieldMetadataDecoratorParams, @@ -21,14 +22,17 @@ export function FieldMetadata( const isSystem = TypedReflect.getMetadata('isSystem', target, fieldKey) ?? false; const gate = TypedReflect.getMetadata('gate', target, fieldKey); - const { joinColumn, ...restParams } = params; + const { joinColumn, standardId, ...restParams } = params; TypedReflect.defineMetadata( 'fieldMetadataMap', { ...existingFieldMetadata, [fieldKey]: generateFieldMetadata( - restParams, + { + ...restParams, + standardId, + }, fieldKey, isNullable, isSystem, @@ -36,10 +40,10 @@ export function FieldMetadata( ), ...(joinColumn && restParams.type === FieldMetadataType.RELATION ? { - // TODO: Should we generate a standardIf for the foreign key ? [joinColumn]: generateFieldMetadata( { ...restParams, + standardId: createDeterministicUuid(standardId), type: FieldMetadataType.UUID, label: `${restParams.label} id (foreign key)`, description: `${restParams.description} id foreign key`, diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/partial-object-metadata.interface.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/partial-object-metadata.interface.ts index e5359310284ed..8ca354b02d44c 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/partial-object-metadata.interface.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/partial-object-metadata.interface.ts @@ -14,7 +14,8 @@ export type PartialObjectMetadata = ReflectObjectMetadata & { export type ComputedPartialObjectMetadata = Omit< PartialObjectMetadata, - 'fields' + 'standardId' | 'fields' > & { + standardId: string | null; fields: ComputedPartialFieldMetadata[]; }; diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/reflect-computed-relation-field-metadata.interface.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/reflect-computed-relation-field-metadata.interface.ts index 14fa48467894d..8067d58d33166 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/reflect-computed-relation-field-metadata.interface.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/interfaces/reflect-computed-relation-field-metadata.interface.ts @@ -6,6 +6,7 @@ import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metada export type DynamicRelationFieldMetadataDecoratorParams = ( oppositeObjectMetadata: ObjectMetadataEntity, ) => { + standardId: string; name: string; label: string; joinColumn: string; diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts index ead89aafe871a..b9b44d2469e79 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-field-metadata.service.ts @@ -71,7 +71,6 @@ export class WorkspaceSyncFieldMetadataService { const standardObjectMetadata = computeStandardObject( { ...customObjectMetadata, - standardId: customObjectMetadata.nameSingular, fields: standardFieldMetadataCollection, }, customObjectMetadata, diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-object-metadata.service.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-object-metadata.service.ts index 685029858b43e..280a8a6a37a00 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-object-metadata.service.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-object-metadata.service.ts @@ -61,7 +61,7 @@ export class WorkspaceSyncObjectMetadataService { workspaceFeatureFlagsMap, ); - // Create map of original and standard object metadata by unique identifier + // Create map of original and standard object metadata by standard ids const originalObjectMetadataMap = mapObjectMetadataByUniqueIdentifier( originalObjectMetadataCollection, ); @@ -75,17 +75,20 @@ export class WorkspaceSyncObjectMetadataService { for (const originalObjectMetadata of originalObjectMetadataCollection.filter( (object) => !object.isCustom, )) { - if (!standardObjectMetadataMap[originalObjectMetadata.nameSingular]) { + if ( + originalObjectMetadata.standardId && + !standardObjectMetadataMap[originalObjectMetadata.standardId] + ) { storage.addDeleteObjectMetadata(originalObjectMetadata); } } // Loop over all standard objects and compare them with the objects in DB - for (const standardObjectName in standardObjectMetadataMap) { + for (const standardObjectId in standardObjectMetadataMap) { const originalObjectMetadata = - originalObjectMetadataMap[standardObjectName]; + originalObjectMetadataMap[standardObjectId]; const standardObjectMetadata = computeStandardObject( - standardObjectMetadataMap[standardObjectName], + standardObjectMetadataMap[standardObjectId], originalObjectMetadata, customObjectMetadataCollection, ); diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-relation-metadata.service.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-relation-metadata.service.ts index e85bfbe673dd7..01e6895413269 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-relation-metadata.service.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/services/workspace-sync-relation-metadata.service.ts @@ -58,6 +58,8 @@ export class WorkspaceSyncRelationMetadataService { // Create map of object metadata & field metadata by unique identifier const originalObjectMetadataMap = mapObjectMetadataByUniqueIdentifier( originalObjectMetadataCollection, + // Relation are based on the singular name + (objectMetadata) => objectMetadata.nameSingular, ); const relationMetadataRepository = manager.getRepository( diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/activity-target.object-metadata.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/activity-target.object-metadata.ts index c23ea3c602702..4ad7522fa91e2 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/activity-target.object-metadata.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/activity-target.object-metadata.ts @@ -68,6 +68,7 @@ export class ActivityTargetObjectMetadata extends BaseObjectMetadata { opportunity: OpportunityObjectMetadata; @DynamicRelationFieldMetadata((oppositeObjectMetadata) => ({ + standardId: activityTargetStandardFieldIds.custom, name: oppositeObjectMetadata.nameSingular, label: oppositeObjectMetadata.labelSingular, description: `ActivityTarget ${oppositeObjectMetadata.labelSingular}`, diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/attachment.object-metadata.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/attachment.object-metadata.ts index b57b4ddfb4b77..99e8d540fe33f 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/attachment.object-metadata.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/attachment.object-metadata.ts @@ -106,6 +106,7 @@ export class AttachmentObjectMetadata extends BaseObjectMetadata { opportunity: OpportunityObjectMetadata; @DynamicRelationFieldMetadata((oppositeObjectMetadata) => ({ + standardId: attachmentStandardFieldIds.custom, name: oppositeObjectMetadata.nameSingular, label: oppositeObjectMetadata.labelSingular, description: `Attachment ${oppositeObjectMetadata.labelSingular}`, diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/favorite.object-metadata.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/favorite.object-metadata.ts index cc0a48c30a6bf..94577224d2f73 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/favorite.object-metadata.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/standard-objects/favorite.object-metadata.ts @@ -78,6 +78,7 @@ export class FavoriteObjectMetadata extends BaseObjectMetadata { opportunity: OpportunityObjectMetadata; @DynamicRelationFieldMetadata((oppositeObjectMetadata) => ({ + standardId: favoriteStandardFieldIds.custom, name: oppositeObjectMetadata.nameSingular, label: oppositeObjectMetadata.labelSingular, description: `Favorite ${oppositeObjectMetadata.labelSingular}`, diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/compute-standard-object.util.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/compute-standard-object.util.ts index 64bfe7d9bc716..8e51141c553ca 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/compute-standard-object.util.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/compute-standard-object.util.ts @@ -7,9 +7,12 @@ import { ComputedPartialFieldMetadata } from 'src/workspace/workspace-sync-metad import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity'; import { generateTargetColumnMap } from 'src/metadata/field-metadata/utils/generate-target-column-map.util'; import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity'; +import { createDeterministicUuid } from 'src/workspace/workspace-sync-metadata/utils/create-deterministic-uuid.util'; export const computeStandardObject = ( - standardObjectMetadata: PartialObjectMetadata, + standardObjectMetadata: Omit & { + standardId: string | null; + }, originalObjectMetadata: ObjectMetadataEntity, customObjectMetadataCollection: ObjectMetadataEntity[] = [], ): ComputedPartialObjectMetadata => { @@ -26,8 +29,6 @@ export const computeStandardObject = ( fields.push({ ...data, ...rest, - // TODO: Add standardIf for dynamic field metadata ? - standardId: '', defaultValue: null, targetColumnMap: {}, }); @@ -35,8 +36,7 @@ export const computeStandardObject = ( // Foreign key fields.push({ ...rest, - // TODO: What should we generate here, and id based on the standardId of the relation field ? - standardId: '', + standardId: createDeterministicUuid(data.standardId), name: joinColumn, type: FieldMetadataType.UUID, label: `${data.label} ID (foreign key)`, diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/create-deterministic-uuid.util.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/create-deterministic-uuid.util.ts new file mode 100644 index 0000000000000..d604d4a1076c0 --- /dev/null +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/create-deterministic-uuid.util.ts @@ -0,0 +1,10 @@ +import { createHash } from 'crypto'; + +export const createDeterministicUuid = (inputUuid: string): string => { + const hash = createHash('sha256').update(inputUuid).digest('hex'); + + return `20202020-4${hash.substring(0, 3)}-${hash.substring( + 3, + 7, + )}-8${hash.substring(7, 10)}-${hash.substring(10, 22)}`; +}; diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/sync-metadata.util.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/sync-metadata.util.ts index c502ccec23606..9fb60169930b8 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/sync-metadata.util.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/sync-metadata.util.ts @@ -10,14 +10,17 @@ export const mapObjectMetadataByUniqueIdentifier = < T extends { standardId: string | null }, >( arr: T[], + keyFactory: (obj: T) => string | null = (obj) => obj.standardId, ): Record => { return arr.reduce( (acc, curr) => { - if (!curr.standardId) { + const key = keyFactory(curr); + + if (!key) { return acc; } - acc[curr.standardId] = { + acc[key] = { ...curr, }; diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync-metadata.module.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync-metadata.module.ts index 81f9988e26214..c460553264f17 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync-metadata.module.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync-metadata.module.ts @@ -40,6 +40,6 @@ import { WorkspaceMigrationBuilderModule } from 'src/workspace/workspace-migrati WorkspaceSyncFieldMetadataService, WorkspaceSyncMetadataService, ], - exports: [WorkspaceSyncMetadataService], + exports: [...workspaceSyncMetadataFactories, WorkspaceSyncMetadataService], }) export class WorkspaceSyncMetadataModule {}