Files
twenty/packages/twenty-server/src/engine/workspace-datasource/workspace-datasource.service.ts
T
Charles Bochet 1e9723a6b7 Fix workspace deletion broken (#14188)
Workspace deletion was broken because workspace schema deletion should
be "CASCADE". Otherwise postgres will refuse to remove a schema with
existing tables

Also, user experience on delete was degraded because of redirect race
condition:
- we were redirecting to /welcome on deletion
- also redirecting to /settings/profile as the system detects
missingPermissionFlag

I'm disabling permission check if the user is not logged in as it does
not makes sense. I don't think this is a big issue but we will likely
revisit this later if we face race condition between Permission checks
redirect and PageChangeEffect. This could also be migrated fairly easily
to PageChangeEffect where we make sure that we only redirect once
2025-08-31 18:59:51 +02:00

84 lines
2.4 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { type DataSource, type EntityManager } from 'typeorm';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import {
PermissionsException,
PermissionsExceptionCode,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
import { getWorkspaceSchemaName } from 'src/engine/workspace-datasource/utils/get-workspace-schema-name.util';
@Injectable()
export class WorkspaceDataSourceService {
constructor(
private readonly dataSourceService: DataSourceService,
@InjectDataSource()
private readonly coreDataSource: DataSource,
) {}
public async checkSchemaExists(workspaceId: string) {
const dataSource =
await this.dataSourceService.getDataSourcesMetadataFromWorkspaceId(
workspaceId,
);
return dataSource.length > 0;
}
/**
*
* Create a new DB schema for a workspace
*
* @param workspaceId
* @returns
*/
public async createWorkspaceDBSchema(workspaceId: string): Promise<string> {
const schemaName = getWorkspaceSchemaName(workspaceId);
const queryRunner = this.coreDataSource.createQueryRunner();
await queryRunner.createSchema(schemaName, true);
await queryRunner.release();
return schemaName;
}
/**
*
* Delete a DB schema for a workspace
*
* @param workspaceId
* @returns
*/
public async deleteWorkspaceDBSchema(workspaceId: string): Promise<void> {
const schemaName = getWorkspaceSchemaName(workspaceId);
const queryRunner = this.coreDataSource.createQueryRunner();
await queryRunner.dropSchema(schemaName, true, true);
await queryRunner.release();
}
public async executeRawQuery(
_query: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_parameters: any[] = [],
_workspaceId: string,
_transactionManager?: EntityManager,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): Promise<any> {
throw new PermissionsException(
'Method not allowed as permissions are not handled at datasource level.',
PermissionsExceptionCode.METHOD_NOT_ALLOWED,
{
userFriendlyMessage:
'This operation is not allowed. Please try a different approach or contact support if you need assistance.',
},
);
}
}