diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql
index f8a2296730..f72273f77f 100644
--- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql
+++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql
@@ -1725,7 +1725,6 @@ enum FeatureFlagKey {
IS_UNIQUE_INDEXES_ENABLED
IS_JSON_FILTER_ENABLED
IS_AI_ENABLED
- IS_APPLICATION_ENABLED
IS_MARKETPLACE_ENABLED
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED
IS_PUBLIC_DOMAIN_ENABLED
diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts
index ba7f3f6b51..fc613776ac 100644
--- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts
+++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts
@@ -1427,7 +1427,7 @@ export interface PublicFeatureFlag {
__typename: 'PublicFeatureFlag'
}
-export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_APPLICATION_ENABLED' | 'IS_MARKETPLACE_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_NAVIGATION_MENU_ITEM_ENABLED' | 'IS_DATE_TIME_WHOLE_DAY_FILTER_ENABLED' | 'IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_USAGE_ANALYTICS_ENABLED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_DIRECT_GRAPHQL_EXECUTION_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_GRAPHQL_QUERY_TIMING_ENABLED' | 'IS_RECORD_TABLE_WIDGET_ENABLED' | 'IS_DATASOURCE_MIGRATED'
+export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_MARKETPLACE_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_NAVIGATION_MENU_ITEM_ENABLED' | 'IS_DATE_TIME_WHOLE_DAY_FILTER_ENABLED' | 'IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_USAGE_ANALYTICS_ENABLED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_DIRECT_GRAPHQL_EXECUTION_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_GRAPHQL_QUERY_TIMING_ENABLED' | 'IS_RECORD_TABLE_WIDGET_ENABLED' | 'IS_DATASOURCE_MIGRATED'
export interface ClientConfig {
appVersion?: Scalars['String']
@@ -9141,7 +9141,6 @@ export const enumFeatureFlagKey = {
IS_UNIQUE_INDEXES_ENABLED: 'IS_UNIQUE_INDEXES_ENABLED' as const,
IS_JSON_FILTER_ENABLED: 'IS_JSON_FILTER_ENABLED' as const,
IS_AI_ENABLED: 'IS_AI_ENABLED' as const,
- IS_APPLICATION_ENABLED: 'IS_APPLICATION_ENABLED' as const,
IS_MARKETPLACE_ENABLED: 'IS_MARKETPLACE_ENABLED' as const,
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED: 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' as const,
IS_PUBLIC_DOMAIN_ENABLED: 'IS_PUBLIC_DOMAIN_ENABLED' as const,
diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts
index 8fdd024070..c85d713329 100644
--- a/packages/twenty-front/src/generated-metadata/graphql.ts
+++ b/packages/twenty-front/src/generated-metadata/graphql.ts
@@ -1702,7 +1702,6 @@ export type FeatureFlag = {
export enum FeatureFlagKey {
IS_AI_ENABLED = 'IS_AI_ENABLED',
- IS_APPLICATION_ENABLED = 'IS_APPLICATION_ENABLED',
IS_COMMAND_MENU_ITEM_ENABLED = 'IS_COMMAND_MENU_ITEM_ENABLED',
IS_CONNECTED_ACCOUNT_MIGRATED = 'IS_CONNECTED_ACCOUNT_MIGRATED',
IS_DATASOURCE_MIGRATED = 'IS_DATASOURCE_MIGRATED',
diff --git a/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx b/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx
index a7f840fa0a..7d98740ccf 100644
--- a/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx
+++ b/packages/twenty-front/src/modules/app/components/SettingsRoutes.tsx
@@ -689,7 +689,7 @@ export const SettingsRoutes = ({ isAdminPageEnabled }: SettingsRoutesProps) => (
}
>
diff --git a/packages/twenty-front/src/modules/settings/hooks/useSettingsNavigationItems.tsx b/packages/twenty-front/src/modules/settings/hooks/useSettingsNavigationItems.tsx
index 37305db70e..55c091b71a 100644
--- a/packages/twenty-front/src/modules/settings/hooks/useSettingsNavigationItems.tsx
+++ b/packages/twenty-front/src/modules/settings/hooks/useSettingsNavigationItems.tsx
@@ -75,9 +75,6 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
(currentUser?.canImpersonate || currentUser?.canAccessFullAdminPanel) ??
false;
const isAIEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
- const isApplicationEnabled = useIsFeatureEnabled(
- FeatureFlagKey.IS_APPLICATION_ENABLED,
- );
const isSupportChatConfigured =
supportChat?.supportDriver === 'FRONT' &&
isNonEmptyString(supportChat.supportFrontChatId);
@@ -178,9 +175,7 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
label: t`Apps`,
path: SettingsPath.Applications,
Icon: IconPlug,
- isHidden:
- !isApplicationEnabled ||
- !permissionMap[PermissionFlagType.WORKSPACE],
+ isHidden: !permissionMap[PermissionFlagType.APPLICATIONS],
modifier: 'new',
},
{
diff --git a/packages/twenty-front/src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts b/packages/twenty-front/src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
index 80c59860a2..e67cf8aa03 100644
--- a/packages/twenty-front/src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
+++ b/packages/twenty-front/src/modules/settings/roles/role-permissions/permission-flags/hooks/useSettingsRolePermissionFlagConfig.ts
@@ -34,9 +34,6 @@ export const useSettingsRolePermissionFlagConfig = ({
assignmentCapabilities,
}: UseSettingsRolePermissionFlagConfigParams = {}): SettingsRolePermissionsSettingPermission[] => {
const isAIEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
- const isApplicationEnabled = useIsFeatureEnabled(
- FeatureFlagKey.IS_APPLICATION_ENABLED,
- );
const {
canBeAssignedToAgents = false,
@@ -180,13 +177,6 @@ export const useSettingsRolePermissionFlagConfig = ({
if (permission.key === PermissionFlagType.AI_SETTINGS && !isAIEnabled) {
return false;
}
- if (
- permission.key === PermissionFlagType.APPLICATIONS &&
- !isApplicationEnabled
- ) {
- return false;
- }
-
if (hasAssignmentCapabilities) {
if (canBeAssignedOnlyToAgents && !permission.isRelevantForAgents) {
return false;
@@ -209,6 +199,5 @@ export const useSettingsRolePermissionFlagConfig = ({
canBeAssignedToUsers,
canBeAssignedToApiKeys,
isAIEnabled,
- isApplicationEnabled,
]);
};
diff --git a/packages/twenty-front/src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutWidgetTypeSelect.tsx b/packages/twenty-front/src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutWidgetTypeSelect.tsx
index c2be42b842..37fc59bfb0 100644
--- a/packages/twenty-front/src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutWidgetTypeSelect.tsx
+++ b/packages/twenty-front/src/modules/side-panel/pages/page-layout/components/SidePanelPageLayoutWidgetTypeSelect.tsx
@@ -86,19 +86,13 @@ export const SidePanelPageLayoutWidgetTypeSelect = () => {
const { removePageLayoutWidgetAndPreservePosition } =
useRemovePageLayoutWidgetAndPreservePosition(pageLayoutId);
- const isApplicationEnabled = useIsFeatureEnabled(
- FeatureFlagKey.IS_APPLICATION_ENABLED,
- );
-
const isRecordTableWidgetEnabled = useIsFeatureEnabled(
FeatureFlagKey.IS_RECORD_TABLE_WIDGET_ENABLED,
);
const { data: frontComponentsData } = useQuery<{
frontComponents: FrontComponent[];
- }>(FIND_MANY_FRONT_COMPONENTS, {
- skip: !isApplicationEnabled,
- });
+ }>(FIND_MANY_FRONT_COMPONENTS);
const frontComponents = frontComponentsData?.frontComponents ?? [];
@@ -288,7 +282,7 @@ export const SidePanelPageLayoutWidgetTypeSelect = () => {
- {isApplicationEnabled && frontComponentsWithSelectItemId.length > 0 && (
+ {frontComponentsWithSelectItemId.length > 0 && (
{frontComponentsWithSelectItemId.map(
({ frontComponent, selectItemId }) => (
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts
index 753e742f5f..31bd5b133f 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts
@@ -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 })
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.resolver.ts
index f92a9ea546..49d2036a4f 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.resolver.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.resolver.ts
@@ -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 })
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.resolver.ts
index 0f4512fe20..5575d88bf5 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.resolver.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.resolver.ts
@@ -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,
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts
index 8433590c78..f04ea1caf6 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts
@@ -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 {
return this.marketplaceQueryService.findManyMarketplaceApps();
}
@Query(() => MarketplaceAppDTO)
- @RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
async findOneMarketplaceApp(
@Args('universalIdentifier') universalIdentifier: string,
): Promise {
@@ -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 })
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-oauth/application-oauth.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-oauth/application-oauth.resolver.ts
index 64af1b2d3f..ba880adb17 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-oauth/application-oauth.resolver.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-oauth/application-oauth.resolver.ts
@@ -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,
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.resolver.ts
index e87e65cb09..47fa498fa0 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.resolver.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.resolver.ts
@@ -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()
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-upgrade/application-upgrade.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-upgrade/application-upgrade.resolver.ts
index 15ca639bb5..91a79d7a34 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-upgrade/application-upgrade.resolver.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-upgrade/application-upgrade.resolver.ts
@@ -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,
diff --git a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts
index 7007a53e03..a62b305604 100644
--- a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts
+++ b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts
@@ -233,7 +233,6 @@ describe('WorkspaceEntityManager', () => {
IS_UNIQUE_INDEXES_ENABLED: false,
IS_JSON_FILTER_ENABLED: false,
IS_AI_ENABLED: false,
- IS_APPLICATION_ENABLED: false,
IS_MARKETPLACE_ENABLED: false,
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED: false,
IS_PUBLIC_DOMAIN_ENABLED: false,
@@ -273,7 +272,6 @@ describe('WorkspaceEntityManager', () => {
IS_UNIQUE_INDEXES_ENABLED: false,
IS_JSON_FILTER_ENABLED: false,
IS_AI_ENABLED: false,
- IS_APPLICATION_ENABLED: false,
IS_PUBLIC_DOMAIN_ENABLED: false,
IS_EMAILING_DOMAIN_ENABLED: false,
IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED: false,
diff --git a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts
index 2d79e7c60c..0c46b56465 100644
--- a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts
+++ b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util.ts
@@ -30,11 +30,6 @@ export const seedFeatureFlags = async ({
workspaceId: workspaceId,
value: true,
},
- {
- key: FeatureFlagKey.IS_APPLICATION_ENABLED,
- workspaceId: workspaceId,
- value: true,
- },
{
key: FeatureFlagKey.IS_PUBLIC_DOMAIN_ENABLED,
workspaceId: workspaceId,
diff --git a/packages/twenty-server/test/integration/metadata/suites/application/__snapshots__/failing-install-application-feature-flag-disabled.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/application/__snapshots__/failing-install-application-feature-flag-disabled.integration-spec.ts.snap
deleted file mode 100644
index 4bb2897930..0000000000
--- a/packages/twenty-server/test/integration/metadata/suites/application/__snapshots__/failing-install-application-feature-flag-disabled.integration-spec.ts.snap
+++ /dev/null
@@ -1,11 +0,0 @@
-// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
-
-exports[`Install application should fail when feature flag is disabled should fail with forbidden error when feature flag is disabled 1`] = `
-{
- "extensions": {
- "code": "FORBIDDEN",
- "userFriendlyMessage": "An error occurred.",
- },
- "message": "Feature flag "IS_APPLICATION_ENABLED" is not enabled for this workspace",
-}
-`;
diff --git a/packages/twenty-server/test/integration/metadata/suites/application/failing-install-application-feature-flag-disabled.integration-spec.ts b/packages/twenty-server/test/integration/metadata/suites/application/failing-install-application-feature-flag-disabled.integration-spec.ts
deleted file mode 100644
index c6f2381129..0000000000
--- a/packages/twenty-server/test/integration/metadata/suites/application/failing-install-application-feature-flag-disabled.integration-spec.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { FeatureFlagKey } from 'twenty-shared/types';
-import { expectOneNotInternalServerErrorSnapshot } from 'test/integration/graphql/utils/expect-one-not-internal-server-error-snapshot.util';
-import { installApplication } from 'test/integration/metadata/suites/application/utils/install-application.util';
-import { updateFeatureFlag } from 'test/integration/metadata/suites/utils/update-feature-flag.util';
-
-describe('Install application should fail when feature flag is disabled', () => {
- beforeAll(async () => {
- await updateFeatureFlag({
- featureFlag: FeatureFlagKey.IS_APPLICATION_ENABLED,
- value: false,
- expectToFail: false,
- });
- });
-
- afterAll(async () => {
- await updateFeatureFlag({
- featureFlag: FeatureFlagKey.IS_APPLICATION_ENABLED,
- value: true,
- expectToFail: false,
- });
- });
-
- it('should fail with forbidden error when feature flag is disabled', async () => {
- const { errors } = await installApplication({
- expectToFail: true,
- input: {
- appRegistrationId: '20202020-0000-0000-0000-000000000000',
- },
- });
-
- expectOneNotInternalServerErrorSnapshot({ errors });
- });
-});
diff --git a/packages/twenty-shared/src/types/FeatureFlagKey.ts b/packages/twenty-shared/src/types/FeatureFlagKey.ts
index 5e0261806a..6437e154ff 100644
--- a/packages/twenty-shared/src/types/FeatureFlagKey.ts
+++ b/packages/twenty-shared/src/types/FeatureFlagKey.ts
@@ -2,7 +2,6 @@ export enum FeatureFlagKey {
IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED',
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
IS_AI_ENABLED = 'IS_AI_ENABLED',
- IS_APPLICATION_ENABLED = 'IS_APPLICATION_ENABLED',
IS_MARKETPLACE_ENABLED = 'IS_MARKETPLACE_ENABLED',
IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED = 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED',
IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED',