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.
This commit is contained in:
Raphaël Bosi
2024-10-08 13:44:16 +02:00
committed by GitHub
parent 66ec70f776
commit e042711f34
11 changed files with 83 additions and 50 deletions

View File

@@ -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: {

View File

@@ -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();

View File

@@ -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();

View File

@@ -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',
};

View File

@@ -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<CalendarEventWorkspaceEntity>,
),
{},
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<CalendarEventWorkspaceEntity>,
),
{},
transactionManager,
);

View File

@@ -171,6 +171,7 @@ export class CalendarChannelSyncStatusService {
syncStatus: CalendarChannelSyncStatus.ACTIVE,
throttleFailureCount: 0,
syncStageStartedAt: null,
syncedAt: new Date().toISOString(),
});
await this.schedulePartialCalendarEventListFetch(calendarChannelIds);

View File

@@ -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 { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
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 { 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 { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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;
};

View File

@@ -146,6 +146,7 @@ export class MessageChannelSyncStatusService {
syncStage: MessageChannelSyncStage.PARTIAL_MESSAGE_LIST_FETCH_PENDING,
throttleFailureCount: 0,
syncStageStartedAt: null,
syncedAt: new Date().toISOString(),
});
}