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.
This commit is contained in:
Marie
2024-10-07 15:29:33 +02:00
committed by GitHub
parent 7bdbbcf72e
commit 94031605ac
6 changed files with 53 additions and 8 deletions

View File

@ -46,4 +46,17 @@ export class FeatureFlagService {
return workspaceFeatureFlagsMap;
}
public async enableFeatureFlags(
keys: FeatureFlagKey[],
workspaceId: string,
): Promise<void> {
await this.featureFlagRepository.upsert(
keys.map((key) => ({ workspaceId, key, value: true })),
{
conflictPaths: ['workspaceId', 'key'],
skipUpdateIfNoValuesChanged: true,
},
);
}
}

View File

@ -2,16 +2,17 @@ import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
import { EmailService } from 'src/engine/core-modules/email/email.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
import { UserService } from 'src/engine/core-modules/user/services/user.service';
import { User } from 'src/engine/core-modules/user/user.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { EmailService } from 'src/engine/core-modules/email/email.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
import { WorkspaceInvitationService } from 'src/engine/core-modules/workspace-invitation/services/workspace-invitation.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
import { WorkspaceService } from './workspace.service';
@ -34,6 +35,10 @@ describe('WorkspaceService', () => {
provide: getRepositoryToken(User, 'core'),
useValue: {},
},
{
provide: getRepositoryToken(FeatureFlagEntity, 'core'),
useValue: {},
},
{
provide: WorkspaceManagerService,
useValue: {},

View File

@ -1,6 +1,6 @@
import { BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { ModuleRef } from '@nestjs/core';
import { InjectRepository } from '@nestjs/typeorm';
import assert from 'assert';
@ -8,6 +8,7 @@ import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
import { Repository } from 'typeorm';
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
import { User } from 'src/engine/core-modules/user/user.entity';
@ -17,6 +18,7 @@ import {
WorkspaceActivationStatus,
} from 'src/engine/core-modules/workspace/workspace.entity';
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
import { DEFAULT_FEATURE_FLAGS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/default-feature-flags';
// eslint-disable-next-line @nx/workspace-inject-workspace-repository
export class WorkspaceService extends TypeOrmQueryService<Workspace> {
@ -29,6 +31,7 @@ export class WorkspaceService extends TypeOrmQueryService<Workspace> {
@InjectRepository(UserWorkspace, 'core')
private readonly userWorkspaceRepository: Repository<UserWorkspace>,
private readonly workspaceManagerService: WorkspaceManagerService,
private readonly featureFlagService: FeatureFlagService,
private readonly billingSubscriptionService: BillingSubscriptionService,
private moduleRef: ModuleRef,
) {
@ -69,6 +72,11 @@ export class WorkspaceService extends TypeOrmQueryService<Workspace> {
activationStatus: WorkspaceActivationStatus.ONGOING_CREATION,
});
await this.featureFlagService.enableFeatureFlags(
DEFAULT_FEATURE_FLAGS,
user.defaultWorkspaceId,
);
await this.workspaceManagerService.init(user.defaultWorkspaceId);
await this.userWorkspaceService.createWorkspaceMember(
user.defaultWorkspaceId,

View File

@ -6,6 +6,7 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
import { BillingModule } from 'src/engine/core-modules/billing/billing.module';
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file-upload.module';
import { FileModule } from 'src/engine/core-modules/file/file.module';
import { OnboardingModule } from 'src/engine/core-modules/onboarding/onboarding.module';
@ -13,12 +14,12 @@ import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-works
import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module';
import { UserWorkspaceResolver } from 'src/engine/core-modules/user-workspace/user-workspace.resolver';
import { User } from 'src/engine/core-modules/user/user.entity';
import { WorkspaceInvitationModule } from 'src/engine/core-modules/workspace-invitation/workspace-invitation.module';
import { WorkspaceWorkspaceMemberListener } from 'src/engine/core-modules/workspace/workspace-workspace-member.listener';
import { WorkspaceResolver } from 'src/engine/core-modules/workspace/workspace.resolver';
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
import { WorkspaceMetadataCacheModule } from 'src/engine/metadata-modules/workspace-metadata-cache/workspace-metadata-cache.module';
import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module';
import { WorkspaceInvitationModule } from 'src/engine/core-modules/workspace-invitation/workspace-invitation.module';
import { workspaceAutoResolverOpts } from './workspace.auto-resolver-opts';
import { Workspace } from './workspace.entity';
@ -40,6 +41,7 @@ import { WorkspaceService } from './services/workspace.service';
),
UserWorkspaceModule,
WorkspaceManagerModule,
FeatureFlagModule,
DataSourceModule,
OnboardingModule,
TypeORMModule,

View File

@ -0,0 +1,6 @@
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
export const DEFAULT_FEATURE_FLAGS = [
FeatureFlagKey.IsSearchEnabled,
FeatureFlagKey.IsWorkspaceMigratedForSearch,
];

View File

@ -1,10 +1,12 @@
import { Injectable, Logger } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
import { DataSource, QueryFailedError } from 'typeorm';
import { DataSource, QueryFailedError, Repository } from 'typeorm';
import { WorkspaceSyncContext } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/workspace-sync-context.interface';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service';
import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
@ -35,6 +37,8 @@ export class WorkspaceSyncMetadataService {
private readonly workspaceSyncIndexMetadataService: WorkspaceSyncIndexMetadataService,
private readonly workspaceSyncObjectMetadataIdentifiersService: WorkspaceSyncObjectMetadataIdentifiersService,
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
@InjectRepository(FeatureFlagEntity, 'core')
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
) {}
/**
@ -149,6 +153,13 @@ export class WorkspaceSyncMetadataService {
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
context.workspaceId,
);
if (workspaceFeatureFlagsMap.IS_SEARCH_ENABLED) {
await this.featureFlagService.enableFeatureFlags(
[FeatureFlagKey.IsWorkspaceMigratedForSearch],
context.workspaceId,
);
}
} catch (error) {
this.logger.error('Sync of standard objects failed with:', error);