[reconnect account] Reseting calendar status and stage on reconnect (#12061)

## Description
When a calendar channel fails, its status is not reset during the
reconnect step.

In some cases, resetting is necessary—especially when we’ve deployed a
fix and users try to reconnect their accounts after the patch.

## Why reseting to initial state
Our processes are idempotent, so we can safely set the status to null to
restart the flow. This approach covers all cases and avoids edge
conditions caused by inconsistent statuses.


Fixes : https://github.com/twentyhq/twenty/issues/12026
This commit is contained in:
Guillim
2025-05-15 14:12:32 +02:00
committed by GitHub
parent 3a494905ec
commit 411cb33137
2 changed files with 83 additions and 0 deletions

View File

@ -20,6 +20,7 @@ import {
CalendarEventListFetchJobData,
} from 'src/modules/calendar/calendar-event-import-manager/jobs/calendar-event-list-fetch.job';
import {
CalendarChannelSyncStage,
CalendarChannelVisibility,
CalendarChannelWorkspaceEntity,
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
@ -305,6 +306,46 @@ export class GoogleAPIsService {
})),
workspaceId,
});
const calendarChannels = await calendarChannelRepository.find({
where: { connectedAccountId: newOrExistingConnectedAccountId },
});
const calendarChannelUpdates = await calendarChannelRepository.update(
{
connectedAccountId: newOrExistingConnectedAccountId,
},
{
syncStage:
CalendarChannelSyncStage.FULL_CALENDAR_EVENT_LIST_FETCH_PENDING,
syncStatus: null,
syncCursor: '',
syncStageStartedAt: null,
},
manager,
);
const calendarChannelMetadata =
await this.objectMetadataRepository.findOneOrFail({
where: { nameSingular: 'calendarChannel', workspaceId },
});
this.workspaceEventEmitter.emitDatabaseBatchEvent({
objectMetadataNameSingular: 'calendarChannel',
action: DatabaseEventAction.UPDATED,
events: calendarChannels.map((calendarChannel) => ({
recordId: calendarChannel.id,
objectMetadata: calendarChannelMetadata,
properties: {
before: calendarChannel,
after: {
...calendarChannel,
...calendarChannelUpdates.raw[0],
},
},
})),
workspaceId,
});
}
},
);

View File

@ -20,6 +20,7 @@ import {
CalendarEventListFetchJobData,
} from 'src/modules/calendar/calendar-event-import-manager/jobs/calendar-event-list-fetch.job';
import {
CalendarChannelSyncStage,
CalendarChannelVisibility,
CalendarChannelWorkspaceEntity,
} from 'src/modules/calendar/common/standard-objects/calendar-channel.workspace-entity';
@ -333,6 +334,47 @@ export class MicrosoftAPIsService {
})),
workspaceId,
});
// now for the calendar channels
const calendarChannels = await calendarChannelRepository.find({
where: { connectedAccountId: newOrExistingConnectedAccountId },
});
const calendarChannelUpdates = await calendarChannelRepository.update(
{
connectedAccountId: newOrExistingConnectedAccountId,
},
{
syncStage:
CalendarChannelSyncStage.FULL_CALENDAR_EVENT_LIST_FETCH_PENDING,
syncStatus: null,
syncCursor: '',
syncStageStartedAt: null,
},
manager,
);
const calendarChannelMetadata =
await this.objectMetadataRepository.findOneOrFail({
where: { nameSingular: 'calendarChannel', workspaceId },
});
this.workspaceEventEmitter.emitDatabaseBatchEvent({
objectMetadataNameSingular: 'calendarChannel',
action: DatabaseEventAction.UPDATED,
events: calendarChannels.map((calendarChannel) => ({
recordId: calendarChannel.id,
objectMetadata: calendarChannelMetadata,
properties: {
before: calendarChannel,
after: {
...calendarChannel,
...calendarChannelUpdates.raw[0],
},
},
})),
workspaceId,
});
}
},
);