mirror of
https://github.com/lingble/twenty.git
synced 2025-10-29 11:52:28 +00:00
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:
@@ -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: {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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',
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
@@ -171,6 +171,7 @@ export class CalendarChannelSyncStatusService {
|
||||
syncStatus: CalendarChannelSyncStatus.ACTIVE,
|
||||
throttleFailureCount: 0,
|
||||
syncStageStartedAt: null,
|
||||
syncedAt: new Date().toISOString(),
|
||||
});
|
||||
|
||||
await this.schedulePartialCalendarEventListFetch(calendarChannelIds);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -146,6 +146,7 @@ export class MessageChannelSyncStatusService {
|
||||
syncStage: MessageChannelSyncStage.PARTIAL_MESSAGE_LIST_FETCH_PENDING,
|
||||
throttleFailureCount: 0,
|
||||
syncStageStartedAt: null,
|
||||
syncedAt: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user