chore: remove IS_APPLICATION_ENABLED feature flag (#19081)

## Summary
- Remove the `IS_APPLICATION_ENABLED` feature flag — application
features are now always enabled
- Remove `@RequireFeatureFlag` decorators and `FeatureFlagGuard` from 7
application resolvers (registration, development, manifest, install,
upgrade, marketplace, oauth)
- Remove frontend feature flag checks: settings navigation visibility,
route protection wrapper, side panel widget type gating, and role
permission flag filtering
- Delete the integration test for disabled-flag behavior
- Clean up seed data, test mocks, and generated schema files
This commit is contained in:
Charles Bochet
2026-03-29 11:43:35 +02:00
committed by GitHub
parent 05c0713474
commit 4d74cc0a28
19 changed files with 13 additions and 180 deletions
@@ -8,7 +8,7 @@ import { Args, Mutation } from '@nestjs/graphql';
import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';
import { PermissionFlagType } from 'twenty-shared/constants';
import { FeatureFlagKey, FileFolder } from 'twenty-shared/types';
import { FileFolder } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import type { FileUpload } from 'graphql-upload/processRequest.mjs';
@@ -41,10 +41,6 @@ import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
import { AuthUserWorkspaceId } from 'src/engine/decorators/auth/auth-user-workspace-id.decorator';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import { DevelopmentGuard } from 'src/engine/guards/development.guard';
import {
FeatureFlagGuard,
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 { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-graphql-api-exception.interceptor';
@@ -56,7 +52,6 @@ import { streamToBuffer } from 'src/utils/stream-to-buffer';
@UseFilters(ApplicationExceptionFilter)
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
DevelopmentGuard,
SettingsPermissionGuard(PermissionFlagType.APPLICATIONS),
)
@@ -72,7 +67,6 @@ export class ApplicationDevelopmentResolver {
) {}
@Mutation(() => DevelopmentApplicationDTO)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async createDevelopmentApplication(
@Args() { universalIdentifier, name }: CreateDevelopmentApplicationInput,
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
@@ -110,7 +104,6 @@ export class ApplicationDevelopmentResolver {
}
@Mutation(() => ApplicationTokenPairDTO)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async generateApplicationToken(
@Args() { applicationId }: GenerateApplicationTokenInput,
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
@@ -126,7 +119,6 @@ export class ApplicationDevelopmentResolver {
}
@Mutation(() => WorkspaceMigrationDTO)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async syncApplication(
@Args() { manifest }: ApplicationInput,
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
@@ -183,7 +175,6 @@ export class ApplicationDevelopmentResolver {
@Mutation(() => FileDTO)
@UseGuards(SettingsPermissionGuard(PermissionFlagType.UPLOAD_FILE))
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async uploadApplicationFile(
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
@Args({ name: 'file', type: () => GraphQLUpload })
@@ -2,8 +2,6 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common';
import { Args, Mutation, Query } from '@nestjs/graphql';
import { PermissionFlagType } from 'twenty-shared/constants';
import { FeatureFlagKey } from 'twenty-shared/types';
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter';
@@ -14,17 +12,13 @@ import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filt
import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe';
import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import {
FeatureFlagGuard,
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';
@UsePipes(ResolverValidationPipe)
@MetadataResolver()
@UseFilters(ApplicationExceptionFilter, AuthGraphqlApiExceptionFilter)
@UseGuards(WorkspaceAuthGuard, FeatureFlagGuard)
@UseGuards(WorkspaceAuthGuard)
export class ApplicationInstallResolver {
constructor(
private readonly applicationService: ApplicationService,
@@ -59,7 +53,6 @@ export class ApplicationInstallResolver {
@Mutation(() => Boolean)
@UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS))
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async installApplication(
@Args('appRegistrationId') appRegistrationId: string,
@Args('version', { type: () => String, nullable: true })
@@ -7,8 +7,6 @@ import {
import { Args, Mutation } from '@nestjs/graphql';
import { PermissionFlagType } from 'twenty-shared/constants';
import { FeatureFlagKey } from 'twenty-shared/types';
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter';
import { ApplicationSyncService } from 'src/engine/core-modules/application/application-manifest/application-sync.service';
@@ -19,10 +17,6 @@ import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filt
import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe';
import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import {
FeatureFlagGuard,
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 { AllUniversalWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-action-common';
@@ -33,7 +27,7 @@ import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/wo
@MetadataResolver()
@UseInterceptors(WorkspaceMigrationGraphqlApiExceptionInterceptor)
@UseFilters(ApplicationExceptionFilter, AuthGraphqlApiExceptionFilter)
@UseGuards(WorkspaceAuthGuard, FeatureFlagGuard)
@UseGuards(WorkspaceAuthGuard)
export class ApplicationManifestResolver {
constructor(
private readonly applicationService: ApplicationService,
@@ -43,7 +37,6 @@ export class ApplicationManifestResolver {
@Mutation(() => Boolean)
@UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS))
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async runWorkspaceMigration(
@Args() { workspaceMigration: { actions } }: RunWorkspaceMigrationInput,
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
@@ -69,7 +62,6 @@ export class ApplicationManifestResolver {
@Mutation(() => Boolean)
@UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS))
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async uninstallApplication(
@Args() { universalIdentifier }: UninstallApplicationInput,
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
@@ -2,8 +2,6 @@ import { UseFilters, UseGuards } from '@nestjs/common';
import { Args, Mutation, Query } from '@nestjs/graphql';
import { PermissionFlagType } from 'twenty-shared/constants';
import { FeatureFlagKey } from 'twenty-shared/types';
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
import { ApplicationRegistrationExceptionFilter } from 'src/engine/core-modules/application/application-registration/application-registration-exception-filter';
import { ApplicationInstallService } from 'src/engine/core-modules/application/application-install/application-install.service';
@@ -11,10 +9,6 @@ import { MarketplaceAppDTO } from 'src/engine/core-modules/application/applicati
import { MarketplaceQueryService } from 'src/engine/core-modules/application/application-marketplace/marketplace-query.service';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import {
FeatureFlagGuard,
RequireFeatureFlag,
} from 'src/engine/guards/feature-flag.guard';
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard';
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
@@ -22,12 +16,7 @@ import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
@MetadataResolver()
@UseFilters(ApplicationRegistrationExceptionFilter)
@UseGuards(
UserAuthGuard,
WorkspaceAuthGuard,
FeatureFlagGuard,
NoPermissionGuard,
)
@UseGuards(UserAuthGuard, WorkspaceAuthGuard, NoPermissionGuard)
export class MarketplaceResolver {
constructor(
private readonly marketplaceQueryService: MarketplaceQueryService,
@@ -35,13 +24,11 @@ export class MarketplaceResolver {
) {}
@Query(() => [MarketplaceAppDTO])
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async findManyMarketplaceApps(): Promise<MarketplaceAppDTO[]> {
return this.marketplaceQueryService.findManyMarketplaceApps();
}
@Query(() => MarketplaceAppDTO)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async findOneMarketplaceApp(
@Args('universalIdentifier') universalIdentifier: string,
): Promise<MarketplaceAppDTO> {
@@ -52,7 +39,6 @@ export class MarketplaceResolver {
@Mutation(() => Boolean)
@UseGuards(SettingsPermissionGuard(PermissionFlagType.MARKETPLACE_APPS))
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async installMarketplaceApp(
@Args('universalIdentifier') universalIdentifier: string,
@Args('version', { type: () => String, nullable: true })
@@ -1,8 +1,6 @@
import { UseFilters, UseGuards, UsePipes } from '@nestjs/common';
import { Args, Mutation } from '@nestjs/graphql';
import { FeatureFlagKey } from 'twenty-shared/types';
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
import {
ApplicationException,
@@ -14,17 +12,13 @@ import { ApplicationTokenService } from 'src/engine/core-modules/auth/token/serv
import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe';
import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import {
FeatureFlagGuard,
RequireFeatureFlag,
} from 'src/engine/guards/feature-flag.guard';
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
@UsePipes(ResolverValidationPipe)
@MetadataResolver()
@UseFilters(AuthGraphqlApiExceptionFilter)
@UseGuards(WorkspaceAuthGuard, FeatureFlagGuard)
@UseGuards(WorkspaceAuthGuard)
export class ApplicationOAuthResolver {
constructor(
private readonly applicationTokenService: ApplicationTokenService,
@@ -32,7 +26,6 @@ export class ApplicationOAuthResolver {
@Mutation(() => ApplicationTokenPairDTO)
@UseGuards(NoPermissionGuard)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async renewApplicationToken(
@Args('applicationRefreshToken') applicationRefreshToken: string,
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
@@ -3,7 +3,7 @@ import { Args, Mutation, Query } from '@nestjs/graphql';
import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';
import { PermissionFlagType } from 'twenty-shared/constants';
import { FeatureFlagKey, FileFolder } from 'twenty-shared/types';
import { FileFolder } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import type { FileUpload } from 'graphql-upload/processRequest.mjs';
@@ -40,10 +40,6 @@ import { UserEntity } from 'src/engine/core-modules/user/user.entity';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import {
FeatureFlagGuard,
RequireFeatureFlag,
} from 'src/engine/guards/feature-flag.guard';
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard';
import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard';
@@ -73,8 +69,7 @@ export class ApplicationRegistrationResolver {
return this.applicationRegistrationService.findPublicByClientId(clientId);
}
@UseGuards(WorkspaceAuthGuard, FeatureFlagGuard, NoPermissionGuard)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@UseGuards(WorkspaceAuthGuard, NoPermissionGuard)
@Query(() => ApplicationRegistrationEntity, { nullable: true })
async findApplicationRegistrationByUniversalIdentifier(
@Args('universalIdentifier') universalIdentifier: string,
@@ -86,10 +81,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Query(() => [ApplicationRegistrationEntity])
async findManyApplicationRegistrations(
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
@@ -99,10 +92,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Query(() => ApplicationRegistrationEntity)
async findOneApplicationRegistration(
@Args('id') id: string,
@@ -113,10 +104,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Query(() => ApplicationRegistrationStatsDTO)
async findApplicationRegistrationStats(
@Args('id') id: string,
@@ -127,10 +116,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Mutation(() => CreateApplicationRegistrationDTO)
async createApplicationRegistration(
@Args('input') input: CreateApplicationRegistrationInput,
@@ -146,10 +133,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Mutation(() => ApplicationRegistrationEntity)
async updateApplicationRegistration(
@Args('input') input: UpdateApplicationRegistrationInput,
@@ -160,10 +145,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Mutation(() => Boolean)
async deleteApplicationRegistration(
@Args('id') id: string,
@@ -174,10 +157,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Mutation(() => RotateClientSecretDTO)
async rotateApplicationRegistrationClientSecret(
@Args('id') id: string,
@@ -194,10 +175,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Query(() => [ApplicationRegistrationVariableEntity])
async findApplicationRegistrationVariables(
@Args('applicationRegistrationId') applicationRegistrationId: string,
@@ -211,10 +190,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Mutation(() => ApplicationRegistrationVariableEntity)
async createApplicationRegistrationVariable(
@Args('input') input: CreateApplicationRegistrationVariableInput,
@@ -228,10 +205,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Mutation(() => ApplicationRegistrationVariableEntity)
async updateApplicationRegistrationVariable(
@Args('input') input: UpdateApplicationRegistrationVariableInput,
@@ -245,10 +220,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Mutation(() => Boolean)
async deleteApplicationRegistrationVariable(
@Args('id') id: string,
@@ -262,10 +235,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.MARKETPLACE_APPS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Mutation(() => ApplicationRegistrationEntity)
async uploadAppTarball(
@Args({ name: 'file', type: () => GraphQLUpload })
@@ -293,10 +264,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.API_KEYS_AND_WEBHOOKS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Query(() => String, { nullable: true })
async applicationRegistrationTarballUrl(
@Args('id') id: string,
@@ -323,10 +292,8 @@ export class ApplicationRegistrationResolver {
@UseGuards(
WorkspaceAuthGuard,
FeatureFlagGuard,
SettingsPermissionGuard(PermissionFlagType.APPLICATIONS),
)
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
@Mutation(() => ApplicationRegistrationEntity)
async transferApplicationRegistrationOwnership(
@Args()
@@ -2,17 +2,11 @@ import { UseFilters, UseGuards } from '@nestjs/common';
import { Args, Mutation } from '@nestjs/graphql';
import { PermissionFlagType } from 'twenty-shared/constants';
import { FeatureFlagKey } from 'twenty-shared/types';
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter';
import { ApplicationUpgradeService } from 'src/engine/core-modules/application/application-upgrade/application-upgrade.service';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import {
FeatureFlagGuard,
RequireFeatureFlag,
} from 'src/engine/guards/feature-flag.guard';
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard';
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
@@ -20,12 +14,7 @@ import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
@MetadataResolver()
@UseFilters(ApplicationExceptionFilter)
@UseGuards(
UserAuthGuard,
WorkspaceAuthGuard,
FeatureFlagGuard,
NoPermissionGuard,
)
@UseGuards(UserAuthGuard, WorkspaceAuthGuard, NoPermissionGuard)
export class ApplicationUpgradeResolver {
constructor(
private readonly applicationUpgradeService: ApplicationUpgradeService,
@@ -33,7 +22,6 @@ export class ApplicationUpgradeResolver {
@Mutation(() => Boolean)
@UseGuards(SettingsPermissionGuard(PermissionFlagType.MARKETPLACE_APPS))
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async upgradeApplication(
@Args('appRegistrationId') appRegistrationId: string,
@Args('targetVersion') targetVersion: string,