diff --git a/packages/twenty-server/src/engine/core-modules/onboarding/onboarding.module.ts b/packages/twenty-server/src/engine/core-modules/onboarding/onboarding.module.ts index b5daa947c0..c7a98ec374 100644 --- a/packages/twenty-server/src/engine/core-modules/onboarding/onboarding.module.ts +++ b/packages/twenty-server/src/engine/core-modules/onboarding/onboarding.module.ts @@ -1,13 +1,20 @@ import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; import { BillingModule } from 'src/engine/core-modules/billing/billing.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { OnboardingResolver } from 'src/engine/core-modules/onboarding/onboarding.resolver'; import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service'; import { UserVarsModule } from 'src/engine/core-modules/user/user-vars/user-vars.module'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; @Module({ - imports: [BillingModule, UserVarsModule, FeatureFlagModule], + imports: [ + BillingModule, + UserVarsModule, + FeatureFlagModule, + TypeOrmModule.forFeature([WorkspaceEntity]), + ], exports: [OnboardingService], providers: [OnboardingService, OnboardingResolver], }) diff --git a/packages/twenty-server/src/engine/core-modules/onboarding/onboarding.service.ts b/packages/twenty-server/src/engine/core-modules/onboarding/onboarding.service.ts index e926ee5b3b..6bb3bbfb66 100644 --- a/packages/twenty-server/src/engine/core-modules/onboarding/onboarding.service.ts +++ b/packages/twenty-server/src/engine/core-modules/onboarding/onboarding.service.ts @@ -1,9 +1,10 @@ import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; import { isNonEmptyString } from '@sniptt/guards'; import { isDefined } from 'twenty-shared/utils'; import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; -import { type QueryRunner } from 'typeorm'; +import { type QueryRunner, Repository } from 'typeorm'; import { BillingService } from 'src/engine/core-modules/billing/services/billing.service'; import { OnboardingStatus } from 'src/engine/core-modules/onboarding/enums/onboarding-status.enum'; @@ -32,6 +33,8 @@ export class OnboardingService { private readonly billingService: BillingService, private readonly userVarsService: UserVarsService, private readonly twentyConfigService: TwentyConfigService, + @InjectRepository(WorkspaceEntity) + private readonly workspaceRepository: Repository, ) {} private isWorkspaceActivationPending(workspace: WorkspaceEntity) { @@ -40,7 +43,25 @@ export class OnboardingService { ); } - async getOnboardingStatus(user: UserEntity, workspace: WorkspaceEntity) { + async getOnboardingStatus({ + user, + workspaceId, + }: { + user: UserEntity; + workspaceId: string; + }): Promise { + // We always read the workspace directly from the database here (bypassing + // the per-instance core entity cache) so that onboardingStatus reflects the + // freshest activationStatus right after activateWorkspace, even when a + // sibling server instance still has a stale cached workspace. + const workspace = await this.workspaceRepository.findOne({ + where: { id: workspaceId }, + }); + + if (!isDefined(workspace)) { + return null; + } + if ( await this.billingService.isSubscriptionIncompleteOnboardingStatus( workspace.id, diff --git a/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts index 6739394079..416546fe03 100644 --- a/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/user/user.resolver.ts @@ -557,7 +557,10 @@ export class UserResolver { ): Promise { if (!workspace) return null; - return this.onboardingService.getOnboardingStatus(user, workspace); + return this.onboardingService.getOnboardingStatus({ + user, + workspaceId: workspace.id, + }); } @ResolveField(() => WorkspaceEntity, {