From e042711f34de599a4696dbd60747ef419cc8c27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Bosi?= <71827178+bosiraphael@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:44:16 +0200 Subject: [PATCH] Fixes on messaging and calendar (#7485) Fix syncedAt no longer been set on message sync. Fix calendar data model: - Add `syncedAt` to `CalendarChannelWorkspaceEntity` - Move `recurringEventExternalId` from `CalendarEventWorkspaceEntity` to `CalendarChannelEventAssociationWorkspaceEntity` since the id is relative to one channel Fix save queries on calendar sync after regression. --- .../generated/mock-metadata-query-result.ts | 22 -------- .../calendar-channel-event-association.ts | 2 + .../workspace/calendar-events.ts | 2 - .../constants/standard-field-ids.ts | 3 +- .../services/calendar-save-events.service.ts | 55 ++++++++++++++++--- .../calendar-channel-sync-status.service.ts | 1 + ...nnel-event-association.workspace-entity.ts | 24 +++++--- .../calendar-channel.workspace-entity.ts | 10 ++++ .../calendar-event.workspace-entity.ts | 9 --- .../calendar/common/types/calendar-event.ts | 2 + .../message-channel-sync-status.service.ts | 1 + 11 files changed, 82 insertions(+), 49 deletions(-) diff --git a/packages/twenty-front/src/testing/mock-data/generated/mock-metadata-query-result.ts b/packages/twenty-front/src/testing/mock-data/generated/mock-metadata-query-result.ts index 6832293415c8..86428fa72919 100644 --- a/packages/twenty-front/src/testing/mock-data/generated/mock-metadata-query-result.ts +++ b/packages/twenty-front/src/testing/mock-data/generated/mock-metadata-query-result.ts @@ -9080,28 +9080,6 @@ export const mockedStandardObjectMetadataQueryResult: ObjectMetadataItemsQuery = relationDefinition: null, }, }, - { - __typename: 'fieldEdge', - node: { - __typename: 'field', - settings: {}, - id: '567c7852-6dc5-4c6e-826d-e4b253614e60', - type: 'TEXT', - name: 'recurringEventExternalId', - label: 'Recurring Event ID', - description: 'Recurring Event ID', - icon: 'IconHistory', - isCustom: false, - isActive: true, - isSystem: false, - isNullable: false, - createdAt: '2024-09-25T13:45:32.757Z', - updatedAt: '2024-09-25T13:45:32.757Z', - defaultValue: "''", - options: null, - relationDefinition: null, - }, - }, { __typename: 'fieldEdge', node: { diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-channel-event-association.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-channel-event-association.ts index 59530a45edd3..7e20a6ab5a33 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-channel-event-association.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-channel-event-association.ts @@ -14,6 +14,7 @@ export const seedCalendarChannelEventAssociations = async ( 'calendarChannelId', 'calendarEventId', 'eventExternalId', + 'recurringEventExternalId', ]) .orIgnore() .values([ @@ -22,6 +23,7 @@ export const seedCalendarChannelEventAssociations = async ( calendarChannelId: '59efdefe-a40f-4faf-bb9f-c6f9945b8203', calendarEventId: '86083141-1c0e-494c-a1b6-85b1c6fefaa5', eventExternalId: 'exampleExternalId', + recurringEventExternalId: 'exampleRecurringExternalId', }, ]) .execute(); diff --git a/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts b/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts index 7624c290cb7d..6969213f7689 100644 --- a/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts +++ b/packages/twenty-server/src/database/typeorm-seeds/workspace/calendar-events.ts @@ -24,7 +24,6 @@ export const seedCalendarEvents = async ( 'conferenceSolution', 'conferenceLinkPrimaryLinkLabel', 'conferenceLinkPrimaryLinkUrl', - 'recurringEventExternalId', ]) .orIgnore() .values([ @@ -43,7 +42,6 @@ export const seedCalendarEvents = async ( conferenceSolution: 'Zoom', conferenceLinkPrimaryLinkLabel: 'https://zoom.us/j/1234567890', conferenceLinkPrimaryLinkUrl: 'https://zoom.us/j/1234567890', - recurringEventExternalId: 'recurring1', }, ]) .execute(); diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts index 6243016b8f73..b2f3e87ae6d7 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids.ts @@ -63,6 +63,7 @@ export const CALENDAR_CHANNEL_EVENT_ASSOCIATION_STANDARD_FIELD_IDS = { calendarChannel: '20202020-93ee-4da4-8d58-0282c4a9cb7d', calendarEvent: '20202020-5aa5-437e-bb86-f42d457783e3', eventExternalId: '20202020-9ec8-48bb-b279-21d0734a75a1', + recurringEventExternalId: '20202020-c58f-4c69-9bf8-9518fa31aa50', }; export const CALENDAR_CHANNEL_STANDARD_FIELD_IDS = { @@ -78,6 +79,7 @@ export const CALENDAR_CHANNEL_STANDARD_FIELD_IDS = { syncStatus: '20202020-7116-41da-8b4b-035975c4eb6a', syncStage: '20202020-6246-42e6-b5cd-003bd921782c', syncStageStartedAt: '20202020-a934-46f1-a8e7-9568b1e3a53e', + syncedAt: '20202020-2ff5-4f70-953a-3d0d36357576', }; export const CALENDAR_EVENT_PARTICIPANT_STANDARD_FIELD_IDS = { @@ -103,7 +105,6 @@ export const CALENDAR_EVENT_STANDARD_FIELD_IDS = { iCalUID: '20202020-f24b-45f4-b6a3-d2f9fcb98714', conferenceSolution: '20202020-1c3f-4b5a-b526-5411a82179eb', conferenceLink: '20202020-35da-43ef-9ca0-e936e9dc237b', - recurringEventExternalId: '20202020-4b96-43d0-8156-4c7a9717635c', calendarChannelEventAssociations: '20202020-bdf8-4572-a2cc-ecbb6bcc3a02', calendarEventParticipants: '20202020-e07e-4ccb-88f5-6f3d00458eec', }; diff --git a/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/services/calendar-save-events.service.ts b/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/services/calendar-save-events.service.ts index 8c71c73f1fc8..7552722e02cc 100644 --- a/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/services/calendar-save-events.service.ts +++ b/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/services/calendar-save-events.service.ts @@ -7,12 +7,10 @@ import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queu import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service'; import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type'; import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager'; -import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter'; import { injectIdsInCalendarEvents } from 'src/modules/calendar/calendar-event-import-manager/utils/inject-ids-in-calendar-events.util'; import { CalendarEventParticipantService } from 'src/modules/calendar/calendar-event-participant-manager/services/calendar-event-participant.service'; import { CalendarChannelEventAssociationWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity'; import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity'; -import { CalendarEventParticipantWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event-participant.workspace-entity'; import { CalendarEventWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event.workspace-entity'; import { CalendarEventWithParticipants } from 'src/modules/calendar/common/types/calendar-event'; import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity'; @@ -28,7 +26,6 @@ export class CalendarSaveEventsService { private readonly calendarEventParticipantService: CalendarEventParticipantService, @InjectMessageQueue(MessageQueue.contactCreationQueue) private readonly messageQueueService: MessageQueueService, - private readonly workspaceEventEmitter: WorkspaceEventEmitter, ) {} public async saveCalendarEventsAndEnqueueContactCreationJob( @@ -103,6 +100,7 @@ export class CalendarSaveEventsService { calendarEventId: calendarEvent.id, eventExternalId: calendarEvent.externalId, calendarChannelId: calendarChannel.id, + recurringEventExternalId: calendarEvent.recurringEventExternalId, })); const participantsToSave = eventsToSave.flatMap( @@ -113,16 +111,57 @@ export class CalendarSaveEventsService { (event) => event.participants, ); - const savedCalendarEventParticipantsToEmit: CalendarEventParticipantWorkspaceEntity[] = - []; - const workspaceDataSource = await this.twentyORMManager.getDatasource(); await workspaceDataSource?.transaction(async (transactionManager) => { - await calendarEventRepository.save(eventsToSave, {}, transactionManager); + await calendarEventRepository.save( + eventsToSave.map( + (calendarEvent) => + ({ + id: calendarEvent.id, + iCalUID: calendarEvent.iCalUID, + title: calendarEvent.title, + description: calendarEvent.description, + startsAt: calendarEvent.startsAt, + endsAt: calendarEvent.endsAt, + location: calendarEvent.location, + isFullDay: calendarEvent.isFullDay, + isCanceled: calendarEvent.isCanceled, + conferenceSolution: calendarEvent.conferenceSolution, + conferenceLink: { + primaryLinkLabel: calendarEvent.conferenceLinkLabel, + primaryLinkUrl: calendarEvent.conferenceLinkUrl, + }, + externalCreatedAt: calendarEvent.externalCreatedAt, + externalUpdatedAt: calendarEvent.externalUpdatedAt, + }) satisfies DeepPartial, + ), + {}, + transactionManager, + ); await calendarEventRepository.save( - eventsToUpdate, + eventsToUpdate.map( + (calendarEvent) => + ({ + id: calendarEvent.id, + iCalUID: calendarEvent.iCalUID, + title: calendarEvent.title, + description: calendarEvent.description, + startsAt: calendarEvent.startsAt, + endsAt: calendarEvent.endsAt, + location: calendarEvent.location, + isFullDay: calendarEvent.isFullDay, + isCanceled: calendarEvent.isCanceled, + conferenceSolution: calendarEvent.conferenceSolution, + conferenceLink: { + primaryLinkLabel: calendarEvent.conferenceLinkLabel, + primaryLinkUrl: calendarEvent.conferenceLinkUrl, + }, + externalCreatedAt: calendarEvent.externalCreatedAt, + externalUpdatedAt: calendarEvent.externalUpdatedAt, + }) satisfies DeepPartial, + ), {}, transactionManager, ); diff --git a/packages/twenty-server/src/modules/calendar/common/services/calendar-channel-sync-status.service.ts b/packages/twenty-server/src/modules/calendar/common/services/calendar-channel-sync-status.service.ts index 4940c1db01eb..c0fe5278f898 100644 --- a/packages/twenty-server/src/modules/calendar/common/services/calendar-channel-sync-status.service.ts +++ b/packages/twenty-server/src/modules/calendar/common/services/calendar-channel-sync-status.service.ts @@ -171,6 +171,7 @@ export class CalendarChannelSyncStatusService { syncStatus: CalendarChannelSyncStatus.ACTIVE, throttleFailureCount: 0, syncStageStartedAt: null, + syncedAt: new Date().toISOString(), }); await this.schedulePartialCalendarEventListFetch(calendarChannelIds); diff --git a/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity.ts b/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity.ts index f1475da3b012..ee74a697eed8 100644 --- a/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity.ts +++ b/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-channel-event-association.workspace-entity.ts @@ -1,16 +1,16 @@ import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface'; import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; -import { CALENDAR_CHANNEL_EVENT_ASSOCIATION_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; -import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; -import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; -import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; -import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator'; -import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; -import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; +import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; +import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; +import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator'; +import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator'; +import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; +import { CALENDAR_CHANNEL_EVENT_ASSOCIATION_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; +import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity'; import { CalendarEventWorkspaceEntity } from 'src/modules/calendar/common/standard-objects/calendar-event.workspace-entity'; @@ -35,6 +35,16 @@ export class CalendarChannelEventAssociationWorkspaceEntity extends BaseWorkspac }) eventExternalId: string; + @WorkspaceField({ + standardId: + CALENDAR_CHANNEL_EVENT_ASSOCIATION_STANDARD_FIELD_IDS.recurringEventExternalId, + type: FieldMetadataType.TEXT, + label: 'Recurring Event ID', + description: 'Recurring Event ID', + icon: 'IconHistory', + }) + recurringEventExternalId: string; + @WorkspaceRelation({ standardId: CALENDAR_CHANNEL_EVENT_ASSOCIATION_STANDARD_FIELD_IDS.calendarChannel, diff --git a/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity.ts b/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity.ts index b6bb2b803af7..fca6a0b01369 100644 --- a/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity.ts +++ b/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity.ts @@ -270,6 +270,16 @@ export class CalendarChannelWorkspaceEntity extends BaseWorkspaceEntity { }) syncCursor: string; + @WorkspaceField({ + standardId: CALENDAR_CHANNEL_STANDARD_FIELD_IDS.syncedAt, + type: FieldMetadataType.DATE_TIME, + label: 'Last sync date', + description: 'Last sync date', + icon: 'IconHistory', + }) + @WorkspaceIsNullable() + syncedAt: string | null; + @WorkspaceField({ standardId: CALENDAR_CHANNEL_STANDARD_FIELD_IDS.syncStageStartedAt, type: FieldMetadataType.DATE_TIME, diff --git a/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts b/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts index 55ede657ae96..4e4bbbf8615b 100644 --- a/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts +++ b/packages/twenty-server/src/modules/calendar/common/standard-objects/calendar-event.workspace-entity.ts @@ -145,15 +145,6 @@ export class CalendarEventWorkspaceEntity extends BaseWorkspaceEntity { @WorkspaceIsNullable() conferenceLink: LinksMetadata; - @WorkspaceField({ - standardId: CALENDAR_EVENT_STANDARD_FIELD_IDS.recurringEventExternalId, - type: FieldMetadataType.TEXT, - label: 'Recurring Event ID', - description: 'Recurring Event ID', - icon: 'IconHistory', - }) - recurringEventExternalId: string; - @WorkspaceRelation({ standardId: CALENDAR_EVENT_STANDARD_FIELD_IDS.calendarChannelEventAssociations, diff --git a/packages/twenty-server/src/modules/calendar/common/types/calendar-event.ts b/packages/twenty-server/src/modules/calendar/common/types/calendar-event.ts index ae817cc3fae7..50517314f4c3 100644 --- a/packages/twenty-server/src/modules/calendar/common/types/calendar-event.ts +++ b/packages/twenty-server/src/modules/calendar/common/types/calendar-event.ts @@ -36,6 +36,7 @@ export type CalendarEventParticipantWithCalendarEventId = export type CalendarEventWithParticipants = CalendarEvent & { externalId: string; + recurringEventExternalId?: string; participants: CalendarEventParticipant[]; status: string; }; @@ -43,6 +44,7 @@ export type CalendarEventWithParticipants = CalendarEvent & { export type CalendarEventWithParticipantsAndCalendarEventId = CalendarEvent & { id: string; externalId: string; + recurringEventExternalId?: string; participants: CalendarEventParticipantWithCalendarEventId[]; status: string; }; diff --git a/packages/twenty-server/src/modules/messaging/common/services/message-channel-sync-status.service.ts b/packages/twenty-server/src/modules/messaging/common/services/message-channel-sync-status.service.ts index 35affc12d9a7..970290c35841 100644 --- a/packages/twenty-server/src/modules/messaging/common/services/message-channel-sync-status.service.ts +++ b/packages/twenty-server/src/modules/messaging/common/services/message-channel-sync-status.service.ts @@ -146,6 +146,7 @@ export class MessageChannelSyncStatusService { syncStage: MessageChannelSyncStage.PARTIAL_MESSAGE_LIST_FETCH_PENDING, throttleFailureCount: 0, syncStageStartedAt: null, + syncedAt: new Date().toISOString(), }); }