Remove sync-metadata and IS_WORKSPACE_CREATION_V2_ENABLED feature flag (#16997)
# Introduction Followup of https://github.com/twentyhq/twenty/pull/17001#pullrequestreview-3638508738 close https://github.com/twentyhq/core-team-issues/issues/1910 We've completely decom the `sync-metadata` in production. We're now then removing its implementation in favor of the v2. ## TODO: - [x] Remove sync-metadata implem and commands - [x] Remove workspace decorators - [x] Type each deprecated field to deprecated on their workspaceEntity - [x] Remove the `workspace-sync-metadata` folder entirely - [x] remove workspace migration - [x] workspace migration removal migration - [x] remove the `v2` references from workspace manager file names - [x] remove the `v2` references from workspace manager modules - [ ] Double check impact on translation file path updates ## Note - Removed the gate logic - Remains some service v2 naming, serverless needs to be migrated on v2 fully - Removed workspaceMigration service app health consumption, making it always returning up ( no more down ) cc @FelixMalfait ( quite obsolete health check now, will require complete refactor once we introduce inter app dependency etc )
This commit is contained in:
@@ -11,7 +11,7 @@ import {
|
||||
} from 'typeorm';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Index('IDX_API_KEY_WORKSPACE_ID', ['workspaceId'])
|
||||
@Entity({ name: 'apiKey', schema: 'core' })
|
||||
|
||||
+6
-6
@@ -10,15 +10,15 @@ import { DatabaseEventTriggerModule } from 'src/engine/metadata-modules/database
|
||||
import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
|
||||
import { ObjectPermissionModule } from 'src/engine/metadata-modules/object-permission/object-permission.module';
|
||||
import { PermissionFlagModule } from 'src/engine/metadata-modules/permission-flag/permission-flag.module';
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
import { RoleModule } from 'src/engine/metadata-modules/role/role.module';
|
||||
import { RouteTriggerModule } from 'src/engine/metadata-modules/route-trigger/route-trigger.module';
|
||||
import { ServerlessFunctionLayerModule } from 'src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.module';
|
||||
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
|
||||
import { WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/workspace-migration-builder-graphql-api-exception.interceptor';
|
||||
import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module';
|
||||
import { ObjectPermissionModule } from 'src/engine/metadata-modules/object-permission/object-permission.module';
|
||||
import { PermissionFlagModule } from 'src/engine/metadata-modules/permission-flag/permission-flag.module';
|
||||
import { RoleModule } from 'src/engine/metadata-modules/role/role.module';
|
||||
import { WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-builder-graphql-api-exception.interceptor';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
|
||||
|
||||
@Module({
|
||||
@@ -34,7 +34,7 @@ import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-commo
|
||||
DatabaseEventTriggerModule,
|
||||
CronTriggerModule,
|
||||
RouteTriggerModule,
|
||||
WorkspaceMigrationV2Module,
|
||||
WorkspaceMigrationModule,
|
||||
PermissionsModule,
|
||||
RoleModule,
|
||||
ObjectPermissionModule,
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ import { ServerlessFunctionLayerService } from 'src/engine/metadata-modules/serv
|
||||
import { ServerlessFunctionV2Service } from 'src/engine/metadata-modules/serverless-function/services/serverless-function-v2.service';
|
||||
import { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type';
|
||||
import { computeMetadataNameFromLabelOrThrow } from 'src/engine/metadata-modules/utils/compute-metadata-name-from-label-or-throw.util';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
export class ApplicationSyncService {
|
||||
|
||||
@@ -17,7 +17,7 @@ import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/ag
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto';
|
||||
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Entity({ name: 'application', schema: 'core' })
|
||||
@ObjectType('Application')
|
||||
|
||||
@@ -16,7 +16,7 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat
|
||||
import { RequireFeatureFlag } from 'src/engine/guards/feature-flag.guard';
|
||||
import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/workspace-migration-builder-graphql-api-exception.interceptor';
|
||||
import { WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-builder-graphql-api-exception.interceptor';
|
||||
|
||||
@UseGuards(
|
||||
WorkspaceAuthGuard,
|
||||
|
||||
+3
-4
@@ -1,5 +1,6 @@
|
||||
import { ObjectType } from '@nestjs/graphql';
|
||||
|
||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
@@ -10,12 +11,10 @@ import {
|
||||
Unique,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||
|
||||
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
||||
import { EntityRelation } from 'src/engine/workspace-manager/workspace-migration/types/entity-relation.interface';
|
||||
|
||||
@Entity({
|
||||
name: 'applicationVariable',
|
||||
@@ -55,7 +54,7 @@ export class ApplicationVariableEntity {
|
||||
},
|
||||
)
|
||||
@JoinColumn({ name: 'applicationId' })
|
||||
application: Relation<ApplicationEntity> | null;
|
||||
application: EntityRelation<ApplicationEntity> | null;
|
||||
|
||||
@CreateDateColumn({ type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import {
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Entity({ name: 'approvedAccessDomain', schema: 'core' })
|
||||
@ObjectType('ApprovedAccessDomain')
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ import {
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { BillingEntitlementEntity } from 'src/engine/core-modules/billing/entities/billing-entitlement.entity';
|
||||
import { BillingSubscriptionEntity } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Entity({ name: 'billingCustomer', schema: 'core' })
|
||||
@ObjectType('BillingCustomer')
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import {
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { BillingCustomerEntity } from 'src/engine/core-modules/billing/entities/billing-customer.entity';
|
||||
import { BillingEntitlementKey } from 'src/engine/core-modules/billing/enums/billing-entitlement-key.enum';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Entity({ name: 'billingEntitlement', schema: 'core' })
|
||||
@ObjectType('BillingEntitlement')
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ import { BillingSubscriptionItemEntity } from 'src/engine/core-modules/billing/e
|
||||
import { BillingSubscriptionCollectionMethod } from 'src/engine/core-modules/billing/enums/billing-subscription-collection-method.enum';
|
||||
import { SubscriptionInterval } from 'src/engine/core-modules/billing/enums/billing-subscription-interval.enum';
|
||||
import { SubscriptionStatus } from 'src/engine/core-modules/billing/enums/billing-subscription-status.enum';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
registerEnumType(SubscriptionStatus, { name: 'SubscriptionStatus' });
|
||||
registerEnumType(SubscriptionInterval, { name: 'SubscriptionInterval' });
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import {
|
||||
EmailingDomainStatus,
|
||||
} from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain';
|
||||
import { VerificationRecord } from 'src/engine/core-modules/emailing-domain/drivers/types/verifications-record';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Entity({ name: 'emailingDomain', schema: 'core' })
|
||||
@ObjectType('EmailingDomain')
|
||||
|
||||
-1
@@ -10,6 +10,5 @@ export enum FeatureFlagKey {
|
||||
IS_DASHBOARD_V2_ENABLED = 'IS_DASHBOARD_V2_ENABLED',
|
||||
IS_TIMELINE_ACTIVITY_MIGRATED = 'IS_TIMELINE_ACTIVITY_MIGRATED',
|
||||
IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED = 'IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED',
|
||||
IS_WORKSPACE_CREATION_V2_ENABLED = 'IS_WORKSPACE_CREATION_V2_ENABLED',
|
||||
IS_IF_ELSE_ENABLED = 'IS_IF_ELSE_ENABLED',
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Entity({ name: 'featureFlag', schema: 'core' })
|
||||
@ObjectType('FeatureFlag')
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
PrimaryGeneratedColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Entity('file')
|
||||
@ObjectType('File')
|
||||
|
||||
@@ -7,7 +7,6 @@ import { AppHealthIndicator } from 'src/engine/core-modules/health/indicators/ap
|
||||
import { MetricsModule } from 'src/engine/core-modules/metrics/metrics.module';
|
||||
import { RedisClientModule } from 'src/engine/core-modules/redis-client/redis-client.module';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
|
||||
import { ConnectedAccountHealth } from './indicators/connected-account.health';
|
||||
import { DatabaseHealthIndicator } from './indicators/database.health';
|
||||
@@ -17,7 +16,6 @@ import { WorkerHealthIndicator } from './indicators/worker.health';
|
||||
imports: [
|
||||
TerminusModule,
|
||||
RedisClientModule,
|
||||
WorkspaceMigrationModule,
|
||||
TypeOrmModule.forFeature([WorkspaceEntity]),
|
||||
MetricsModule,
|
||||
],
|
||||
|
||||
-127
@@ -6,12 +6,10 @@ import { type Repository } from 'typeorm';
|
||||
|
||||
import { AppHealthIndicator } from 'src/engine/core-modules/health/indicators/app.health';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||
|
||||
describe('AppHealthIndicator', () => {
|
||||
let service: AppHealthIndicator;
|
||||
let workspaceRepository: jest.Mocked<Repository<WorkspaceEntity>>;
|
||||
let workspaceMigrationService: jest.Mocked<WorkspaceMigrationService>;
|
||||
let healthIndicatorService: jest.Mocked<HealthIndicatorService>;
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -19,11 +17,6 @@ describe('AppHealthIndicator', () => {
|
||||
count: jest.fn(),
|
||||
} as any;
|
||||
|
||||
workspaceMigrationService = {
|
||||
getWorkspacesWithPendingMigrations: jest.fn(),
|
||||
countWorkspacesWithPendingMigrations: jest.fn(),
|
||||
} as any;
|
||||
|
||||
healthIndicatorService = {
|
||||
check: jest.fn().mockReturnValue({
|
||||
up: jest.fn().mockImplementation((data) => ({
|
||||
@@ -42,10 +35,6 @@ describe('AppHealthIndicator', () => {
|
||||
provide: getRepositoryToken(WorkspaceEntity),
|
||||
useValue: workspaceRepository,
|
||||
},
|
||||
{
|
||||
provide: WorkspaceMigrationService,
|
||||
useValue: workspaceMigrationService,
|
||||
},
|
||||
{
|
||||
provide: HealthIndicatorService,
|
||||
useValue: healthIndicatorService,
|
||||
@@ -68,104 +57,18 @@ describe('AppHealthIndicator', () => {
|
||||
it('should return up status when no issues and no pending migrations', async () => {
|
||||
workspaceRepository.count.mockResolvedValue(2);
|
||||
|
||||
workspaceMigrationService.countWorkspacesWithPendingMigrations.mockResolvedValue(
|
||||
0,
|
||||
);
|
||||
workspaceMigrationService.getWorkspacesWithPendingMigrations.mockResolvedValue(
|
||||
[],
|
||||
);
|
||||
|
||||
const result = await service.isHealthy();
|
||||
|
||||
expect(result.app.status).toBe('up');
|
||||
expect(result.app.details.overview.totalWorkspacesCount).toBe(2);
|
||||
expect(result.app.details.overview.erroredWorkspaceCount).toBe(0);
|
||||
expect(result.app.details.erroredWorkspace).toBe(null);
|
||||
expect(result.app.details.system.nodeVersion).toBeDefined();
|
||||
expect(result.app.details.system.timestamp).toBeDefined();
|
||||
});
|
||||
|
||||
it('should return down status when there are pending migrations', async () => {
|
||||
workspaceRepository.count.mockResolvedValue(5);
|
||||
|
||||
// Mock a total count that's higher than the sample
|
||||
workspaceMigrationService.countWorkspacesWithPendingMigrations.mockResolvedValue(
|
||||
10,
|
||||
);
|
||||
|
||||
workspaceMigrationService.getWorkspacesWithPendingMigrations.mockResolvedValue(
|
||||
[
|
||||
{
|
||||
workspaceId: 'workspace1',
|
||||
pendingMigrations: 1,
|
||||
},
|
||||
{
|
||||
workspaceId: 'workspace2',
|
||||
pendingMigrations: 3,
|
||||
},
|
||||
{
|
||||
workspaceId: 'workspace3',
|
||||
pendingMigrations: 2,
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
const result = await service.isHealthy();
|
||||
|
||||
expect(result.app.status).toBe('down');
|
||||
expect(result.app.message).toBe(
|
||||
'Found 10 workspaces with pending migrations',
|
||||
);
|
||||
|
||||
expect(result.app.details).toEqual({
|
||||
system: {
|
||||
nodeVersion: process.version,
|
||||
timestamp: expect.any(String),
|
||||
},
|
||||
overview: {
|
||||
totalWorkspacesCount: 5,
|
||||
erroredWorkspaceCount: 10,
|
||||
},
|
||||
erroredWorkspace: [
|
||||
{
|
||||
workspaceId: 'workspace1',
|
||||
pendingMigrations: 1,
|
||||
},
|
||||
{
|
||||
workspaceId: 'workspace2',
|
||||
pendingMigrations: 3,
|
||||
},
|
||||
{
|
||||
workspaceId: 'workspace3',
|
||||
pendingMigrations: 2,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle errors gracefully and maintain state history', async () => {
|
||||
workspaceRepository.count.mockRejectedValue(
|
||||
new Error('Database connection failed'),
|
||||
);
|
||||
|
||||
const result = await service.isHealthy();
|
||||
|
||||
expect(result.app.status).toBe('down');
|
||||
expect(result.app.message).toBe('Database connection failed');
|
||||
expect(result.app.details.system.nodeVersion).toBeDefined();
|
||||
expect(result.app.details.system.timestamp).toBeDefined();
|
||||
expect(result.app.details.stateHistory).toBeDefined();
|
||||
});
|
||||
|
||||
it('should maintain state history across health checks', async () => {
|
||||
// First check - healthy state
|
||||
workspaceRepository.count.mockResolvedValue(2);
|
||||
workspaceMigrationService.countWorkspacesWithPendingMigrations.mockResolvedValue(
|
||||
0,
|
||||
);
|
||||
workspaceMigrationService.getWorkspacesWithPendingMigrations.mockResolvedValue(
|
||||
[],
|
||||
);
|
||||
|
||||
await service.isHealthy();
|
||||
|
||||
@@ -181,34 +84,4 @@ describe('AppHealthIndicator', () => {
|
||||
expect(result.app.details.stateHistory.timestamp).toBeDefined();
|
||||
expect(result.app.details.stateHistory.details).toBeDefined();
|
||||
});
|
||||
|
||||
it('should sample workspaces with pending migrations up to limit', async () => {
|
||||
workspaceRepository.count.mockResolvedValue(1000);
|
||||
|
||||
// Mock a total count higher than the sample
|
||||
workspaceMigrationService.countWorkspacesWithPendingMigrations.mockResolvedValue(
|
||||
500,
|
||||
);
|
||||
|
||||
const sampleWorkspaces = Array(300)
|
||||
.fill(0)
|
||||
.map((_, i) => ({
|
||||
workspaceId: `workspace${i}`,
|
||||
pendingMigrations: (i % 3) + 1,
|
||||
}));
|
||||
|
||||
workspaceMigrationService.getWorkspacesWithPendingMigrations.mockResolvedValue(
|
||||
sampleWorkspaces,
|
||||
);
|
||||
|
||||
const result = await service.isHealthy();
|
||||
|
||||
expect(result.app.status).toBe('down');
|
||||
expect(result.app.message).toBe(
|
||||
'Found 500 workspaces with pending migrations',
|
||||
);
|
||||
expect(result.app.details.overview.totalWorkspacesCount).toBe(1000);
|
||||
expect(result.app.details.overview.erroredWorkspaceCount).toBe(500);
|
||||
expect(result.app.details.erroredWorkspace.length).toBe(300);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,7 +9,6 @@ import { Repository } from 'typeorm';
|
||||
|
||||
import { HealthStateManager } from 'src/engine/core-modules/health/utils/health-state-manager.util';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||
|
||||
@Injectable()
|
||||
export class AppHealthIndicator {
|
||||
@@ -19,21 +18,13 @@ export class AppHealthIndicator {
|
||||
private readonly healthIndicatorService: HealthIndicatorService,
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
private readonly workspaceMigrationService: WorkspaceMigrationService,
|
||||
) {}
|
||||
|
||||
// TODO refactor, a workspace health should be based on its app versioning
|
||||
async isHealthy(): Promise<HealthIndicatorResult> {
|
||||
const indicator = this.healthIndicatorService.check('app');
|
||||
|
||||
try {
|
||||
const totalErroredWorkspacesCount =
|
||||
await this.workspaceMigrationService.countWorkspacesWithPendingMigrations();
|
||||
|
||||
const sampledErroredWorkspaces =
|
||||
await this.workspaceMigrationService.getWorkspacesWithPendingMigrations(
|
||||
500,
|
||||
);
|
||||
|
||||
const totalWorkspaceCount = await this.workspaceRepository.count();
|
||||
|
||||
const details = {
|
||||
@@ -43,29 +34,14 @@ export class AppHealthIndicator {
|
||||
},
|
||||
overview: {
|
||||
totalWorkspacesCount: totalWorkspaceCount,
|
||||
erroredWorkspaceCount: totalErroredWorkspacesCount,
|
||||
erroredWorkspaceCount: 0,
|
||||
},
|
||||
erroredWorkspace:
|
||||
totalErroredWorkspacesCount > 0
|
||||
? sampledErroredWorkspaces.map((workspace) => ({
|
||||
workspaceId: workspace.workspaceId,
|
||||
pendingMigrations: workspace.pendingMigrations,
|
||||
}))
|
||||
: null,
|
||||
erroredWorkspace: 0,
|
||||
};
|
||||
|
||||
if (totalErroredWorkspacesCount === 0) {
|
||||
this.stateManager.updateState(details);
|
||||
|
||||
return indicator.up({ details });
|
||||
}
|
||||
|
||||
this.stateManager.updateState(details);
|
||||
|
||||
return indicator.down({
|
||||
message: `Found ${totalErroredWorkspacesCount} workspaces with pending migrations`,
|
||||
details,
|
||||
});
|
||||
return indicator.up({ details });
|
||||
} catch (error) {
|
||||
const stateWithAge = this.stateManager.getStateWithAge();
|
||||
|
||||
|
||||
@@ -48,8 +48,6 @@ import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twent
|
||||
import { WorkspaceNotFoundDefaultError } from 'src/engine/core-modules/workspace/workspace.exception';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects';
|
||||
import { shouldExcludeFromWorkspaceApi } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/should-exclude-from-workspace-api.util';
|
||||
import { getServerUrl } from 'src/utils/get-server-url';
|
||||
|
||||
@Injectable()
|
||||
@@ -127,20 +125,7 @@ export class OpenApiService {
|
||||
return schema;
|
||||
}
|
||||
|
||||
const workspaceFeatureFlagsMap =
|
||||
await this.featureFlagService.getWorkspaceFeatureFlagsMap(workspace.id);
|
||||
|
||||
const filteredObjectMetadataItems = flatObjectMetadataArray.filter(
|
||||
(item) => {
|
||||
return !shouldExcludeFromWorkspaceApi(
|
||||
item,
|
||||
standardObjectMetadataDefinitions,
|
||||
workspaceFeatureFlagsMap,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
schema.paths = filteredObjectMetadataItems.reduce((paths, item) => {
|
||||
schema.paths = flatObjectMetadataArray.reduce((paths, item) => {
|
||||
paths[`/${item.namePlural}`] = computeManyResultPath(
|
||||
item,
|
||||
flatObjectMetadataMaps,
|
||||
@@ -204,7 +189,7 @@ export class OpenApiService {
|
||||
},
|
||||
} as OpenAPIV3_1.PathItemObject;
|
||||
|
||||
schema.webhooks = filteredObjectMetadataItems.reduce(
|
||||
schema.webhooks = flatObjectMetadataArray.reduce(
|
||||
(paths, item) => {
|
||||
paths[
|
||||
this.createWebhookEventName(
|
||||
@@ -251,7 +236,7 @@ export class OpenApiService {
|
||||
schema.components = {
|
||||
...schema.components, // components.securitySchemes is defined in base Schema
|
||||
schemas: computeSchemaComponents(
|
||||
filteredObjectMetadataItems,
|
||||
flatObjectMetadataArray,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
),
|
||||
@@ -262,7 +247,7 @@ export class OpenApiService {
|
||||
},
|
||||
};
|
||||
|
||||
schema.tags = computeSchemaTags(filteredObjectMetadataItems);
|
||||
schema.tags = computeSchemaTags(flatObjectMetadataArray);
|
||||
|
||||
return schema;
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import {
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Entity({ name: 'postgresCredentials', schema: 'core' })
|
||||
@ObjectType('PostgresCredentials')
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import {
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Entity({ name: 'publicDomain', schema: 'core' })
|
||||
@ObjectType('PublicDomain')
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import {
|
||||
} from 'typeorm';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
export enum IdentityProviderType {
|
||||
OIDC = 'OIDC',
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import type { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
import type { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
|
||||
export const formatValidationErrors = (
|
||||
error: WorkspaceMigrationBuilderExceptionV2,
|
||||
error: WorkspaceMigrationBuilderException,
|
||||
): string => {
|
||||
const report = error.failedWorkspaceMigrationBuildResult.report;
|
||||
const errorMessages: string[] = [];
|
||||
|
||||
@@ -1393,16 +1393,6 @@ export class ConfigVariables {
|
||||
@IsOptional()
|
||||
IS_MAPS_AND_ADDRESS_AUTOCOMPLETE_ENABLED = false;
|
||||
|
||||
@ConfigVariablesMetadata({
|
||||
group: ConfigVariablesGroup.OTHER,
|
||||
description:
|
||||
'Enable or disable workspace creation through v2 workspaceMigration',
|
||||
type: ConfigVariableType.BOOLEAN,
|
||||
isEnvOnly: true,
|
||||
})
|
||||
@IsOptional()
|
||||
IS_WORKSPACE_CREATION_V2_ENABLED = false;
|
||||
|
||||
@ConfigVariablesMetadata({
|
||||
group: ConfigVariablesGroup.OTHER,
|
||||
isSensitive: true,
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import { TwoFactorAuthenticationMethodSummaryDto } from 'src/engine/core-modules
|
||||
import { TwoFactorAuthenticationMethodEntity } from 'src/engine/core-modules/two-factor-authentication/entities/two-factor-authentication-method.entity';
|
||||
import { UserEntity } from 'src/engine/core-modules/user/user.entity';
|
||||
import { ObjectPermissionDTO } from 'src/engine/metadata-modules/object-permission/dtos/object-permission.dto';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
registerEnumType(PermissionFlagType, {
|
||||
name: 'PermissionFlagType',
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from 'typeorm';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Index('IDX_WEBHOOK_WORKSPACE_ID', ['workspaceId'])
|
||||
@Entity({ name: 'webhook', schema: 'core' })
|
||||
|
||||
+2
-12
@@ -17,7 +17,6 @@ import { DnsManagerService } from 'src/engine/core-modules/dns-manager/services/
|
||||
import { CustomDomainManagerService } from 'src/engine/core-modules/domain/custom-domain-manager/services/custom-domain-manager.service';
|
||||
import { SubdomainManagerService } from 'src/engine/core-modules/domain/subdomain-manager/services/subdomain-manager.service';
|
||||
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import {
|
||||
FileWorkspaceFolderDeletionJob,
|
||||
@@ -47,7 +46,7 @@ import { PermissionsService } from 'src/engine/metadata-modules/permissions/perm
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
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';
|
||||
import { DEFAULT_FEATURE_FLAGS } from 'src/engine/workspace-manager/workspace-migration/constant/default-feature-flags';
|
||||
import { extractVersionMajorMinorPatch } from 'src/utils/version/extract-version-major-minor-patch';
|
||||
|
||||
@Injectable()
|
||||
@@ -245,17 +244,8 @@ export class WorkspaceService extends TypeOrmQueryService<WorkspaceEntity> {
|
||||
activationStatus: WorkspaceActivationStatus.ONGOING_CREATION,
|
||||
});
|
||||
|
||||
const isV2SyncEnabled = this.twentyConfigService.get(
|
||||
'IS_WORKSPACE_CREATION_V2_ENABLED',
|
||||
);
|
||||
|
||||
await this.featureFlagService.enableFeatureFlags(
|
||||
[
|
||||
...DEFAULT_FEATURE_FLAGS,
|
||||
...(isV2SyncEnabled
|
||||
? [FeatureFlagKey.IS_WORKSPACE_CREATION_V2_ENABLED]
|
||||
: []),
|
||||
],
|
||||
DEFAULT_FEATURE_FLAGS,
|
||||
workspace.id,
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user