Skip to content

Commit 9403160

Browse files
authored
Prepare workspace for search features at creation (#7467)
Enabling feature flags IsSearchEnabled and IsWorkspaceMigratedForSearch at workspace creation to ensure workspaces have the searchVector fields and indexes created. For the feature to be enabled in the front-end we will also need IsQueryRunnerTwentyORMEnabled to be enabled but that is an independent topic.
1 parent 7bdbbcf commit 9403160

File tree

6 files changed

+52
-7
lines changed

6 files changed

+52
-7
lines changed

packages/twenty-server/src/engine/core-modules/feature-flag/services/feature-flag.service.ts

+13
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,17 @@ export class FeatureFlagService {
4646

4747
return workspaceFeatureFlagsMap;
4848
}
49+
50+
public async enableFeatureFlags(
51+
keys: FeatureFlagKey[],
52+
workspaceId: string,
53+
): Promise<void> {
54+
await this.featureFlagRepository.upsert(
55+
keys.map((key) => ({ workspaceId, key, value: true })),
56+
{
57+
conflictPaths: ['workspaceId', 'key'],
58+
skipUpdateIfNoValuesChanged: true,
59+
},
60+
);
61+
}
4962
}

packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.spec.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ import { Test, TestingModule } from '@nestjs/testing';
22
import { getRepositoryToken } from '@nestjs/typeorm';
33

44
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
5+
import { EmailService } from 'src/engine/core-modules/email/email.service';
6+
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
7+
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
58
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
69
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
710
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
811
import { UserService } from 'src/engine/core-modules/user/services/user.service';
912
import { User } from 'src/engine/core-modules/user/user.entity';
13+
import { WorkspaceInvitationService } from 'src/engine/core-modules/workspace-invitation/services/workspace-invitation.service';
1014
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
11-
import { EmailService } from 'src/engine/core-modules/email/email.service';
12-
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
1315
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
14-
import { WorkspaceInvitationService } from 'src/engine/core-modules/workspace-invitation/services/workspace-invitation.service';
1516

1617
import { WorkspaceService } from './workspace.service';
1718

@@ -34,6 +35,10 @@ describe('WorkspaceService', () => {
3435
provide: getRepositoryToken(User, 'core'),
3536
useValue: {},
3637
},
38+
{
39+
provide: getRepositoryToken(FeatureFlagEntity, 'core'),
40+
useValue: {},
41+
},
3742
{
3843
provide: WorkspaceManagerService,
3944
useValue: {},

packages/twenty-server/src/engine/core-modules/workspace/services/workspace.service.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { BadRequestException } from '@nestjs/common';
2-
import { InjectRepository } from '@nestjs/typeorm';
32
import { ModuleRef } from '@nestjs/core';
3+
import { InjectRepository } from '@nestjs/typeorm';
44

55
import assert from 'assert';
66

77
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
88
import { Repository } from 'typeorm';
99

1010
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
11+
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
1112
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
1213
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
1314
import { User } from 'src/engine/core-modules/user/user.entity';
@@ -17,6 +18,7 @@ import {
1718
WorkspaceActivationStatus,
1819
} from 'src/engine/core-modules/workspace/workspace.entity';
1920
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
21+
import { DEFAULT_FEATURE_FLAGS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/default-feature-flags';
2022

2123
// eslint-disable-next-line @nx/workspace-inject-workspace-repository
2224
export class WorkspaceService extends TypeOrmQueryService<Workspace> {
@@ -29,6 +31,7 @@ export class WorkspaceService extends TypeOrmQueryService<Workspace> {
2931
@InjectRepository(UserWorkspace, 'core')
3032
private readonly userWorkspaceRepository: Repository<UserWorkspace>,
3133
private readonly workspaceManagerService: WorkspaceManagerService,
34+
private readonly featureFlagService: FeatureFlagService,
3235
private readonly billingSubscriptionService: BillingSubscriptionService,
3336
private moduleRef: ModuleRef,
3437
) {
@@ -69,6 +72,11 @@ export class WorkspaceService extends TypeOrmQueryService<Workspace> {
6972
activationStatus: WorkspaceActivationStatus.ONGOING_CREATION,
7073
});
7174

75+
await this.featureFlagService.enableFeatureFlags(
76+
DEFAULT_FEATURE_FLAGS,
77+
user.defaultWorkspaceId,
78+
);
79+
7280
await this.workspaceManagerService.init(user.defaultWorkspaceId);
7381
await this.userWorkspaceService.createWorkspaceMember(
7482
user.defaultWorkspaceId,

packages/twenty-server/src/engine/core-modules/workspace/workspace.module.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
66
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
77
import { BillingModule } from 'src/engine/core-modules/billing/billing.module';
88
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
9+
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
910
import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file-upload.module';
1011
import { FileModule } from 'src/engine/core-modules/file/file.module';
1112
import { OnboardingModule } from 'src/engine/core-modules/onboarding/onboarding.module';
1213
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
1314
import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module';
1415
import { UserWorkspaceResolver } from 'src/engine/core-modules/user-workspace/user-workspace.resolver';
1516
import { User } from 'src/engine/core-modules/user/user.entity';
17+
import { WorkspaceInvitationModule } from 'src/engine/core-modules/workspace-invitation/workspace-invitation.module';
1618
import { WorkspaceWorkspaceMemberListener } from 'src/engine/core-modules/workspace/workspace-workspace-member.listener';
1719
import { WorkspaceResolver } from 'src/engine/core-modules/workspace/workspace.resolver';
1820
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
1921
import { WorkspaceMetadataCacheModule } from 'src/engine/metadata-modules/workspace-metadata-cache/workspace-metadata-cache.module';
2022
import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module';
21-
import { WorkspaceInvitationModule } from 'src/engine/core-modules/workspace-invitation/workspace-invitation.module';
2223

2324
import { workspaceAutoResolverOpts } from './workspace.auto-resolver-opts';
2425
import { Workspace } from './workspace.entity';
@@ -40,6 +41,7 @@ import { WorkspaceService } from './services/workspace.service';
4041
),
4142
UserWorkspaceModule,
4243
WorkspaceManagerModule,
44+
FeatureFlagModule,
4345
DataSourceModule,
4446
OnboardingModule,
4547
TypeORMModule,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
2+
3+
export const DEFAULT_FEATURE_FLAGS = [
4+
FeatureFlagKey.IsSearchEnabled,
5+
FeatureFlagKey.IsWorkspaceMigratedForSearch,
6+
];

packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { Injectable, Logger } from '@nestjs/common';
2-
import { InjectDataSource } from '@nestjs/typeorm';
2+
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
33

4-
import { DataSource, QueryFailedError } from 'typeorm';
4+
import { DataSource, QueryFailedError, Repository } from 'typeorm';
55

66
import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface';
77

8+
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
9+
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
810
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
911
import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service';
1012
import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
@@ -35,6 +37,8 @@ export class WorkspaceSyncMetadataService {
3537
private readonly workspaceSyncIndexMetadataService: WorkspaceSyncIndexMetadataService,
3638
private readonly workspaceSyncObjectMetadataIdentifiersService: WorkspaceSyncObjectMetadataIdentifiersService,
3739
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
40+
@InjectRepository(FeatureFlagEntity, 'core')
41+
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
3842
) {}
3943

4044
/**
@@ -149,6 +153,13 @@ export class WorkspaceSyncMetadataService {
149153
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
150154
context.workspaceId,
151155
);
156+
157+
if (workspaceFeatureFlagsMap.IS_SEARCH_ENABLED) {
158+
await this.featureFlagService.enableFeatureFlags(
159+
[FeatureFlagKey.IsWorkspaceMigratedForSearch],
160+
context.workspaceId,
161+
);
162+
}
152163
} catch (error) {
153164
this.logger.error('Sync of standard objects failed with:', error);
154165

0 commit comments

Comments
 (0)