Fix workspace invite onboarding loop (#16444)

- The issue is that the listener is not triggered if they are no change
to the workspaceMember (which happens when name is already filled
through GoogleSSO)

Fixes https://github.com/twentyhq/twenty/issues/16440
This commit is contained in:
Charles Bochet
2025-12-09 19:18:17 +01:00
committed by GitHub
parent 3e9820fa8d
commit 83fc434c5d
6 changed files with 49 additions and 84 deletions
@@ -1,75 +0,0 @@
import { Injectable } from '@nestjs/common';
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
import {
HandleWorkspaceMemberDeletedJob,
type HandleWorkspaceMemberDeletedJobData,
} from 'src/engine/core-modules/workspace/handle-workspace-member-deleted.job';
import { type ObjectRecordDeleteEvent } from 'src/engine/core-modules/event-emitter/types/object-record-delete.event';
import { type ObjectRecordUpdateEvent } from 'src/engine/core-modules/event-emitter/types/object-record-update.event';
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event-batch.type';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { OnDatabaseBatchEvent } from 'src/engine/api/graphql/graphql-query-runner/decorators/on-database-batch-event.decorator';
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
@Injectable()
export class WorkspaceWorkspaceMemberListener {
constructor(
private readonly onboardingService: OnboardingService,
@InjectMessageQueue(MessageQueue.workspaceQueue)
private readonly messageQueueService: MessageQueueService,
) {}
@OnDatabaseBatchEvent('workspaceMember', DatabaseEventAction.UPDATED)
async handleUpdateEvent(
payload: WorkspaceEventBatch<
ObjectRecordUpdateEvent<WorkspaceMemberWorkspaceEntity>
>,
) {
await Promise.all(
payload.events.map((eventPayload) => {
const { firstName: firstNameAfter, lastName: lastNameAfter } =
eventPayload.properties.after.name;
if (firstNameAfter === '' && lastNameAfter === '') {
return;
}
if (!eventPayload.userId) {
return;
}
return this.onboardingService.setOnboardingCreateProfilePending({
userId: eventPayload.userId,
workspaceId: payload.workspaceId,
value: false,
});
}),
);
}
@OnDatabaseBatchEvent('workspaceMember', DatabaseEventAction.DELETED)
async handleDeleteEvent(
payload: WorkspaceEventBatch<
ObjectRecordDeleteEvent<WorkspaceMemberWorkspaceEntity>
>,
) {
await Promise.all(
payload.events.map((eventPayload) => {
const userId = eventPayload.properties.before.userId;
if (!userId) {
return;
}
return this.messageQueueService.add<HandleWorkspaceMemberDeletedJobData>(
HandleWorkspaceMemberDeletedJob.name,
{ workspaceId: payload.workspaceId, userId },
);
}),
);
}
}
@@ -25,7 +25,6 @@ import { UserEntity } from 'src/engine/core-modules/user/user.entity';
import { CheckCustomDomainValidRecordsCronCommand } from 'src/engine/core-modules/workspace/crons/commands/check-custom-domain-valid-records.cron.command';
import { CheckCustomDomainValidRecordsCronJob } from 'src/engine/core-modules/workspace/crons/jobs/check-custom-domain-valid-records.cron.job';
import { WorkspaceService } from 'src/engine/core-modules/workspace/services/workspace.service';
import { WorkspaceWorkspaceMemberListener } from 'src/engine/core-modules/workspace/workspace-workspace-member.listener';
import { workspaceAutoResolverOpts } from 'src/engine/core-modules/workspace/workspace.auto-resolver-opts';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { WorkspaceResolver } from 'src/engine/core-modules/workspace/workspace.resolver';
@@ -81,7 +80,6 @@ import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-m
providers: [
WorkspaceResolver,
WorkspaceService,
WorkspaceWorkspaceMemberListener,
CheckCustomDomainValidRecordsCronCommand,
CheckCustomDomainValidRecordsCronJob,
],