chore(server): drop unused postgresCredentials feature (#20573)

## Summary

Drops the `postgresCredentials` legacy feature: a never-finished
"postgres proxy" that would have let users query their workspace data
over a standard Postgres connection. Nothing — frontend, e2e, Zapier,
docs, other server code — calls these mutations/query.

## History

- **Introduced** June 2024 (#5767, Thomas Trompette) as "first step for
creating credentials for database proxy", alongside the Postgres FDW /
remote-server work and the custom `twenty-postgres-spilo` image. Planned
follow-ups (provisioning a DB on the proxy, mapping users, exposing it
as a remote server) never landed.
- **Abandoned** January 2026 (#17001, Weiko) when the sibling "remote
integration" feature was removed as a BREAKING CHANGE — "not maintained
for more than a year and never officially launched". The spilo image was
then replaced with vanilla `postgres:16` (#19182, March 2026), retiring
the FDW infrastructure entirely.
- This PR finishes the cleanup: removes the orphaned module, the
`allPostgresCredentials` relation, `JwtTokenTypeEnum.POSTGRES_PROXY` +
payload, the reserved metadata keywords, and adds a 2.5.0 fast instance
command that drops `core.postgresCredentials` (reversible `down`).
Regenerated frontend GraphQL types + SDK metadata client.

## Test plan

- [x] `tsgo --noEmit` clean on twenty-server + twenty-front; lint +
prettier clean on touched files.
- [x] `database:migrate:generate` reports no pending schema diff; server
boots and serves the new schema.
This commit is contained in:
Charles Bochet
2026-05-14 12:04:09 +02:00
committed by GitHub
parent 61683d8bda
commit 0d5617d446
17 changed files with 304 additions and 610 deletions

View File

@@ -2443,13 +2443,6 @@ type ImapSmtpCaldavConnectionSuccess {
connectedAccountId: String!
}
type PostgresCredentials {
id: UUID!
user: String!
password: String!
workspaceId: UUID!
}
type ToolIndexEntry {
name: String!
description: String!
@@ -3062,7 +3055,6 @@ type Query {
getAutoCompleteAddress(address: String!, token: String!, country: String, isFieldCity: Boolean): [AutocompleteResult!]!
getAddressDetails(placeId: String!, token: String!): PlaceDetailsResult!
getUsageAnalytics(input: UsageAnalyticsInput): UsageAnalytics!
getPostgresCredentials: PostgresCredentials
findManyPublicDomains: [PublicDomain!]!
getEmailingDomains: [EmailingDomain!]!
findManyMarketplaceApps: [MarketplaceApp!]!
@@ -3334,8 +3326,6 @@ type Mutation {
startChannelSync(connectedAccountId: UUID!): ChannelSyncSuccess!
saveImapSmtpCaldavAccount(accountOwnerId: UUID!, handle: String!, connectionParameters: EmailAccountConnectionParameters!, id: UUID): ImapSmtpCaldavConnectionSuccess!
updateLabPublicFeatureFlag(input: UpdateLabPublicFeatureFlagInput!): FeatureFlag!
enablePostgresProxy: PostgresCredentials!
disablePostgresProxy: PostgresCredentials!
createPublicDomain(domain: String!, applicationId: String): PublicDomain!
updatePublicDomain(domain: String!, applicationId: String): PublicDomain!
deletePublicDomain(domain: String!): Boolean!

View File

@@ -2124,14 +2124,6 @@ export interface ImapSmtpCaldavConnectionSuccess {
__typename: 'ImapSmtpCaldavConnectionSuccess'
}
export interface PostgresCredentials {
id: Scalars['UUID']
user: Scalars['String']
password: Scalars['String']
workspaceId: Scalars['UUID']
__typename: 'PostgresCredentials'
}
export interface ToolIndexEntry {
name: Scalars['String']
description: Scalars['String']
@@ -2665,7 +2657,6 @@ export interface Query {
getAutoCompleteAddress: AutocompleteResult[]
getAddressDetails: PlaceDetailsResult
getUsageAnalytics: UsageAnalytics
getPostgresCredentials?: PostgresCredentials
findManyPublicDomains: PublicDomain[]
getEmailingDomains: EmailingDomain[]
findManyMarketplaceApps: MarketplaceApp[]
@@ -2870,8 +2861,6 @@ export interface Mutation {
startChannelSync: ChannelSyncSuccess
saveImapSmtpCaldavAccount: ImapSmtpCaldavConnectionSuccess
updateLabPublicFeatureFlag: FeatureFlag
enablePostgresProxy: PostgresCredentials
disablePostgresProxy: PostgresCredentials
createPublicDomain: PublicDomain
updatePublicDomain: PublicDomain
deletePublicDomain: Scalars['Boolean']
@@ -5158,15 +5147,6 @@ export interface ImapSmtpCaldavConnectionSuccessGenqlSelection{
__scalar?: boolean | number
}
export interface PostgresCredentialsGenqlSelection{
id?: boolean | number
user?: boolean | number
password?: boolean | number
workspaceId?: boolean | number
__typename?: boolean | number
__scalar?: boolean | number
}
export interface ToolIndexEntryGenqlSelection{
name?: boolean | number
description?: boolean | number
@@ -5730,7 +5710,6 @@ export interface QueryGenqlSelection{
getAutoCompleteAddress?: (AutocompleteResultGenqlSelection & { __args: {address: Scalars['String'], token: Scalars['String'], country?: (Scalars['String'] | null), isFieldCity?: (Scalars['Boolean'] | null)} })
getAddressDetails?: (PlaceDetailsResultGenqlSelection & { __args: {placeId: Scalars['String'], token: Scalars['String']} })
getUsageAnalytics?: (UsageAnalyticsGenqlSelection & { __args?: {input?: (UsageAnalyticsInput | null)} })
getPostgresCredentials?: PostgresCredentialsGenqlSelection
findManyPublicDomains?: PublicDomainGenqlSelection
getEmailingDomains?: EmailingDomainGenqlSelection
findManyMarketplaceApps?: MarketplaceAppGenqlSelection
@@ -5956,8 +5935,6 @@ export interface MutationGenqlSelection{
startChannelSync?: (ChannelSyncSuccessGenqlSelection & { __args: {connectedAccountId: Scalars['UUID']} })
saveImapSmtpCaldavAccount?: (ImapSmtpCaldavConnectionSuccessGenqlSelection & { __args: {accountOwnerId: Scalars['UUID'], handle: Scalars['String'], connectionParameters: EmailAccountConnectionParameters, id?: (Scalars['UUID'] | null)} })
updateLabPublicFeatureFlag?: (FeatureFlagGenqlSelection & { __args: {input: UpdateLabPublicFeatureFlagInput} })
enablePostgresProxy?: PostgresCredentialsGenqlSelection
disablePostgresProxy?: PostgresCredentialsGenqlSelection
createPublicDomain?: (PublicDomainGenqlSelection & { __args: {domain: Scalars['String'], applicationId?: (Scalars['String'] | null)} })
updatePublicDomain?: (PublicDomainGenqlSelection & { __args: {domain: Scalars['String'], applicationId?: (Scalars['String'] | null)} })
deletePublicDomain?: { __args: {domain: Scalars['String']} }
@@ -7975,14 +7952,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null
const PostgresCredentials_possibleTypes: string[] = ['PostgresCredentials']
export const isPostgresCredentials = (obj?: { __typename?: any } | null): obj is PostgresCredentials => {
if (!obj?.__typename) throw new Error('__typename is missing in "isPostgresCredentials"')
return PostgresCredentials_possibleTypes.includes(obj.__typename)
}
const ToolIndexEntry_possibleTypes: string[] = ['ToolIndexEntry']
export const isToolIndexEntry = (obj?: { __typename?: any } | null): obj is ToolIndexEntry => {
if (!obj?.__typename) throw new Error('__typename is missing in "isToolIndexEntry"')

View File

File diff suppressed because it is too large Load Diff

View File

@@ -2455,11 +2455,9 @@ export type Mutation = {
destroyViewFilterGroup: Scalars['Boolean'];
destroyViewGroup: ViewGroup;
destroyViewSort: Scalars['Boolean'];
disablePostgresProxy: PostgresCredentials;
duplicateDashboard: DuplicatedDashboard;
editSSOIdentityProvider: EditSso;
emailPasswordResetLink: EmailPasswordResetLink;
enablePostgresProxy: PostgresCredentials;
endSubscriptionTrialPeriod: BillingEndTrialPeriod;
evaluateAgentTurn: AgentTurnEvaluation;
executeOneLogicFunction: LogicFunctionExecutionResult;
@@ -4030,14 +4028,6 @@ export type PlaceDetailsResult = {
street?: Maybe<Scalars['String']>;
};
export type PostgresCredentials = {
__typename?: 'PostgresCredentials';
id: Scalars['UUID'];
password: Scalars['String'];
user: Scalars['String'];
workspaceId: Scalars['UUID'];
};
export type PublicApplicationRegistration = {
__typename?: 'PublicApplicationRegistration';
id: Scalars['UUID'];
@@ -4161,7 +4151,6 @@ export type Query = {
getPageLayoutWidget: PageLayoutWidget;
getPageLayoutWidgets: Array<PageLayoutWidget>;
getPageLayouts: Array<PageLayout>;
getPostgresCredentials?: Maybe<PostgresCredentials>;
getPublicWorkspaceDataByDomain: PublicWorkspaceData;
getPublicWorkspaceDataById: PublicWorkspaceDataSummary;
getResourceCreditUsage: Array<BillingResourceCreditUsage>;

View File

@@ -17,7 +17,6 @@ import { BillingSubscriptionEntity } from 'src/engine/core-modules/billing/entit
import { EmailingDomainEntity } from 'src/engine/core-modules/emailing-domain/emailing-domain.entity';
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { FileEntity } from 'src/engine/core-modules/file/entities/file.entity';
import { PostgresCredentialsEntity } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.entity';
import { PublicDomainEntity } from 'src/engine/core-modules/public-domain/public-domain.entity';
import { WorkspaceSSOIdentityProviderEntity } from 'src/engine/core-modules/sso/workspace-sso-identity-provider.entity';
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
@@ -103,7 +102,6 @@ const WORKSPACE_RELATED_ENTITIES: EntityTarget<ObjectLiteral>[] = [
EmailingDomainEntity,
FeatureFlagEntity,
FileEntity,
PostgresCredentialsEntity,
PublicDomainEntity,
WebhookEntity,
WorkspaceSSOIdentityProviderEntity,

View File

@@ -0,0 +1,36 @@
import { type QueryRunner } from 'typeorm';
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
import { type FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
@RegisteredInstanceCommand('2.5.0', 1798500000000)
export class DropPostgresCredentialsTableFastInstanceCommand
implements FastInstanceCommand
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE IF EXISTS "core"."postgresCredentials" DROP CONSTRAINT IF EXISTS "FK_9494639abc06f9c8c3691bf5d22"`,
);
await queryRunner.query(
`DROP TABLE IF EXISTS "core"."postgresCredentials"`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS "core"."postgresCredentials" (
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
"user" character varying NOT NULL,
"passwordHash" character varying NOT NULL,
"createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
"updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
"deletedAt" TIMESTAMP WITH TIME ZONE,
"workspaceId" uuid NOT NULL,
CONSTRAINT "PK_3f9c4cdf895bfea0a6ea15bdd81" PRIMARY KEY ("id")
)`,
);
await queryRunner.query(
`ALTER TABLE "core"."postgresCredentials" ADD CONSTRAINT "FK_9494639abc06f9c8c3691bf5d22" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
);
}
}

View File

@@ -39,6 +39,7 @@ import { EncryptApplicationRegistrationVariableSlowInstanceCommand } from 'src/d
import { EncryptSigningKeyPrivateKeysSlowInstanceCommand } from 'src/database/commands/upgrade-version-command/2-5/2-5-instance-command-slow-1798000007000-encrypt-signing-key-private-keys';
import { EncryptSensitiveConfigStorageSlowInstanceCommand } from 'src/database/commands/upgrade-version-command/2-5/2-5-instance-command-slow-1798000008000-encrypt-sensitive-config-storage';
import { AddSubFieldNameToViewSortFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-5/2-5-instance-command-fast-1778502963794-add-sub-field-name-to-view-sort';
import { DropPostgresCredentialsTableFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-5/2-5-instance-command-fast-1798500000000-drop-postgres-credentials-table';
export const INSTANCE_COMMANDS = [
AddViewFieldGroupIdIndexOnViewFieldFastInstanceCommand,
@@ -80,4 +81,5 @@ export const INSTANCE_COMMANDS = [
EncryptSigningKeyPrivateKeysSlowInstanceCommand,
EncryptSensitiveConfigStorageSlowInstanceCommand,
AddSubFieldNameToViewSortFastInstanceCommand,
DropPostgresCredentialsTableFastInstanceCommand,
];

View File

@@ -43,7 +43,6 @@ export enum JwtTokenTypeEnum {
LOGIN = 'LOGIN',
FILE = 'FILE',
API_KEY = 'API_KEY',
POSTGRES_PROXY = 'POSTGRES_PROXY',
REMOTE_SERVER = 'REMOTE_SERVER',
KEY_ENCRYPTION_KEY = 'KEY_ENCRYPTION_KEY',
APPLICATION_ACCESS = 'APPLICATION_ACCESS',
@@ -138,10 +137,6 @@ export type AccessTokenJwtPayload = CommonPropertiesJwtPayload & {
impersonatedUserWorkspaceId?: string;
};
export type PostgresProxyTokenJwtPayload = CommonPropertiesJwtPayload & {
type: JwtTokenTypeEnum.POSTGRES_PROXY;
};
export type AppOAuthStateJwtPayload = CommonPropertiesJwtPayload & {
type: JwtTokenTypeEnum.APP_OAUTH_STATE;
workspaceId: string;
@@ -170,5 +165,4 @@ export type JwtPayload =
| RefreshTokenJwtPayload
| FileTokenJwtPayload
| FileTokenJwtPayloadLegacy
| PostgresProxyTokenJwtPayload
| AppOAuthStateJwtPayload;

View File

@@ -51,7 +51,6 @@ import { MessagingWebhooksModule } from 'src/engine/core-modules/messaging-webho
import { MetricsModule } from 'src/engine/core-modules/metrics/metrics.module';
import { MetricsService } from 'src/engine/core-modules/metrics/metrics.service';
import { OpenApiModule } from 'src/engine/core-modules/open-api/open-api.module';
import { PostgresCredentialsModule } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.module';
import { PublicDomainModule } from 'src/engine/core-modules/public-domain/public-domain.module';
import { RedisClientModule } from 'src/engine/core-modules/redis-client/redis-client.module';
import { RedisClientService } from 'src/engine/core-modules/redis-client/redis-client.service';
@@ -116,7 +115,6 @@ import { FileModule } from './file/file.module';
PublicDomainModule,
CloudflareModule,
DnsManagerModule,
PostgresCredentialsModule,
WorkflowApiModule,
WorkspaceEventEmitterModule,
ActorModule,

View File

@@ -1,20 +0,0 @@
import { Field, ObjectType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
@ObjectType('PostgresCredentials')
export class PostgresCredentialsDTO {
@IDField(() => UUIDScalarType)
id: string;
@Field()
user: string;
@Field()
password: string;
@Field(() => UUIDScalarType)
workspaceId: string;
}

View File

@@ -1,33 +0,0 @@
import { ObjectType } from '@nestjs/graphql';
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
@Entity({ name: 'postgresCredentials', schema: 'core' })
@ObjectType('PostgresCredentials')
export class PostgresCredentialsEntity extends WorkspaceRelatedEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: false })
user: string;
@Column({ nullable: false })
passwordHash: string;
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ type: 'timestamptz' })
updatedAt: Date;
@Column({ nullable: true, type: 'timestamptz' })
deletedAt: Date;
}

View File

@@ -1,22 +0,0 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { JwtModule } from 'src/engine/core-modules/jwt/jwt.module';
import { PostgresCredentialsEntity } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.entity';
import { PostgresCredentialsResolver } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.resolver';
import { PostgresCredentialsService } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.service';
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
@Module({
imports: [
JwtModule,
TypeOrmModule.forFeature([PostgresCredentialsEntity]),
PermissionsModule,
],
providers: [
PostgresCredentialsResolver,
PostgresCredentialsService,
PostgresCredentialsEntity,
],
})
export class PostgresCredentialsModule {}

View File

@@ -1,44 +0,0 @@
import { UseGuards } from '@nestjs/common';
import { Mutation, Query } from '@nestjs/graphql';
import { PermissionFlagType } from 'twenty-shared/constants';
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
import { PostgresCredentialsDTO } from 'src/engine/core-modules/postgres-credentials/dtos/postgres-credentials.dto';
import { PostgresCredentialsService } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.service';
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
@UseGuards(
WorkspaceAuthGuard,
SettingsPermissionGuard(PermissionFlagType.DATA_MODEL),
)
@MetadataResolver(() => PostgresCredentialsDTO)
export class PostgresCredentialsResolver {
constructor(
private readonly postgresCredentialsService: PostgresCredentialsService,
) {}
@Mutation(() => PostgresCredentialsDTO)
async enablePostgresProxy(
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
) {
return this.postgresCredentialsService.enablePostgresProxy(workspaceId);
}
@Mutation(() => PostgresCredentialsDTO)
async disablePostgresProxy(
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
) {
return this.postgresCredentialsService.disablePostgresProxy(workspaceId);
}
@Query(() => PostgresCredentialsDTO, { nullable: true })
async getPostgresCredentials(
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
) {
return this.postgresCredentialsService.getPostgresCredentials(workspaceId);
}
}

View File

@@ -1,127 +0,0 @@
import { BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { randomBytes } from 'crypto';
import { Repository } from 'typeorm';
import {
decryptText,
encryptText,
} from 'src/engine/core-modules/auth/auth.util';
import { NotFoundError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
import { JwtWrapperService } from 'src/engine/core-modules/jwt/services/jwt-wrapper.service';
import { type PostgresCredentialsDTO } from 'src/engine/core-modules/postgres-credentials/dtos/postgres-credentials.dto';
import { PostgresCredentialsEntity } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.entity';
import { JwtTokenTypeEnum } from 'src/engine/core-modules/auth/types/auth-context.type';
export class PostgresCredentialsService {
constructor(
@InjectRepository(PostgresCredentialsEntity)
private readonly postgresCredentialsRepository: Repository<PostgresCredentialsEntity>,
private readonly jwtWrapperService: JwtWrapperService,
) {}
async enablePostgresProxy(
workspaceId: string,
): Promise<PostgresCredentialsDTO> {
const user = `user_${randomBytes(4).toString('hex')}`;
const password = randomBytes(16).toString('hex');
const key = this.jwtWrapperService.generateAppSecret(
JwtTokenTypeEnum.POSTGRES_PROXY,
workspaceId,
);
const passwordHash = encryptText(password, key);
const existingCredentials =
await this.postgresCredentialsRepository.findOne({
where: {
workspaceId,
},
});
if (existingCredentials) {
throw new BadRequestException(
'Postgres credentials already exist for this workspace',
);
}
const postgresCredentials = await this.postgresCredentialsRepository.create(
{
user,
passwordHash,
workspaceId,
},
);
await this.postgresCredentialsRepository.save(postgresCredentials);
return {
id: postgresCredentials.id,
user,
password,
workspaceId,
};
}
async disablePostgresProxy(
workspaceId: string,
): Promise<PostgresCredentialsDTO> {
const postgresCredentials =
await this.postgresCredentialsRepository.findOne({
where: {
workspaceId,
},
});
if (!postgresCredentials?.id) {
throw new NotFoundError(
'No valid Postgres credentials not found for this workspace',
);
}
await this.postgresCredentialsRepository.delete({
id: postgresCredentials.id,
});
const key = this.jwtWrapperService.generateAppSecret(
JwtTokenTypeEnum.POSTGRES_PROXY,
workspaceId,
);
return {
id: postgresCredentials.id,
user: postgresCredentials.user,
password: decryptText(postgresCredentials.passwordHash, key),
workspaceId: postgresCredentials.workspaceId,
};
}
async getPostgresCredentials(
workspaceId: string,
): Promise<PostgresCredentialsDTO | null> {
const postgresCredentials =
await this.postgresCredentialsRepository.findOne({
where: {
workspaceId,
},
});
if (!postgresCredentials) {
return null;
}
const key = this.jwtWrapperService.generateAppSecret(
JwtTokenTypeEnum.POSTGRES_PROXY,
workspaceId,
);
return {
id: postgresCredentials.id,
user: postgresCredentials.user,
password: decryptText(postgresCredentials.passwordHash, key),
workspaceId: postgresCredentials.workspaceId,
};
}
}

View File

@@ -10,7 +10,6 @@ export const WORKSPACE_ENTITY_NON_CACHED_PROPERTIES = [
'emailingDomains',
'publicDomains',
'workspaceMembersCount',
'allPostgresCredentials',
'workspaceSSOIdentityProviders',
'agents',
'webhooks',

View File

@@ -29,7 +29,6 @@ import { EmailingDomainEntity } from 'src/engine/core-modules/emailing-domain/em
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { FileEntity } from 'src/engine/core-modules/file/entities/file.entity';
import { KeyValuePairEntity } from 'src/engine/core-modules/key-value-pair/key-value-pair.entity';
import { PostgresCredentialsEntity } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.entity';
import { PublicDomainEntity } from 'src/engine/core-modules/public-domain/public-domain.entity';
import { WorkspaceSSOIdentityProviderEntity } from 'src/engine/core-modules/sso/workspace-sso-identity-provider.entity';
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
@@ -180,12 +179,6 @@ export class WorkspaceEntity {
@Column({ type: 'timestamptz', nullable: true })
suspendedAt: Date | null;
@OneToMany(
() => PostgresCredentialsEntity,
(postgresCredentials) => postgresCredentials.workspace,
)
allPostgresCredentials: Relation<PostgresCredentialsEntity[]>;
@OneToMany(
() => WorkspaceSSOIdentityProviderEntity,
(workspaceSSOIdentityProviders) => workspaceSSOIdentityProviders.workspace,

View File

@@ -27,8 +27,6 @@ export const RESERVED_METADATA_NAME_KEYWORDS = [
'pageLayoutTabs',
'pageLayoutWidget',
'pageLayoutWidgets',
'postgresCredential',
'postgresCredentials',
'twoFactorMethod',
'twoFactorMethods',
'user',