f6423f5925
## Summary - **Drop the `objectMetadata.dataSourceId` foreign key and index** via a 1-22 fast instance command — column kept nullable for data preservation - **Delete `DataSourceService`, `DataSourceModule`, and `DataSourceException`** — all code now uses `workspace.databaseSchema` directly - **Remove `IS_DATASOURCE_MIGRATED` feature flag** from default flags and all branching logic - **Simplify workspace/object creation pipelines** — `WorkspaceManagerService`, `DevSeederService`, and the object creation action handler no longer route through `DataSourceService` - **Keep `DataSourceEntity` and the `dataSource` table** for historical data — entity stripped of all ORM relations
159 lines
5.5 KiB
TypeScript
159 lines
5.5 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
|
|
import { Repository } from 'typeorm';
|
|
|
|
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
|
import { FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
|
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
|
|
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
|
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
|
|
import {
|
|
GenerateSdkClientJob,
|
|
GenerateSdkClientJobData,
|
|
} from 'src/engine/core-modules/sdk-client/jobs/generate-sdk-client.job';
|
|
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
|
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
|
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
|
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
|
|
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
|
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
|
import { STANDARD_ROLE } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-role.constant';
|
|
import { TwentyStandardApplicationService } from 'src/engine/workspace-manager/twenty-standard-application/services/twenty-standard-application.service';
|
|
|
|
@Injectable()
|
|
export class WorkspaceManagerService {
|
|
private readonly logger = new Logger(WorkspaceManagerService.name);
|
|
|
|
constructor(
|
|
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
|
@InjectRepository(UserWorkspaceEntity)
|
|
private readonly userWorkspaceRepository: Repository<UserWorkspaceEntity>,
|
|
private readonly roleService: RoleService,
|
|
private readonly userRoleService: UserRoleService,
|
|
private readonly twentyStandardApplicationService: TwentyStandardApplicationService,
|
|
@InjectRepository(WorkspaceEntity)
|
|
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
|
@InjectRepository(RoleEntity)
|
|
private readonly roleRepository: Repository<RoleEntity>,
|
|
private readonly applicationService: ApplicationService,
|
|
@InjectMessageQueue(MessageQueue.workspaceQueue)
|
|
private readonly messageQueueService: MessageQueueService,
|
|
) {}
|
|
|
|
public async init({
|
|
workspace,
|
|
userId,
|
|
}: {
|
|
workspace: WorkspaceEntity;
|
|
userId: string;
|
|
}): Promise<void> {
|
|
const workspaceId = workspace.id;
|
|
const schemaCreationStart = performance.now();
|
|
const schemaName =
|
|
await this.workspaceDataSourceService.createWorkspaceDBSchema(
|
|
workspaceId,
|
|
);
|
|
|
|
const schemaCreationEnd = performance.now();
|
|
|
|
this.logger.log(
|
|
`Schema creation took ${schemaCreationEnd - schemaCreationStart}ms`,
|
|
);
|
|
|
|
const dataSourceMetadataCreationStart = performance.now();
|
|
|
|
await this.workspaceRepository.update(workspaceId, {
|
|
databaseSchema: schemaName,
|
|
});
|
|
|
|
await this.applicationService.createTwentyStandardApplication({
|
|
workspaceId,
|
|
});
|
|
|
|
await this.twentyStandardApplicationService.synchronizeTwentyStandardApplicationOrThrow(
|
|
{
|
|
workspaceId,
|
|
},
|
|
);
|
|
|
|
const dataSourceMetadataCreationEnd = performance.now();
|
|
|
|
this.logger.log(
|
|
`Metadata creation took ${dataSourceMetadataCreationEnd - dataSourceMetadataCreationStart}ms`,
|
|
);
|
|
|
|
const { workspaceCustomFlatApplication, twentyStandardFlatApplication } =
|
|
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
|
{
|
|
workspaceId,
|
|
},
|
|
);
|
|
|
|
await Promise.all([
|
|
this.messageQueueService.add<GenerateSdkClientJobData>(
|
|
GenerateSdkClientJob.name,
|
|
{
|
|
workspaceId,
|
|
applicationId: twentyStandardFlatApplication.id,
|
|
applicationUniversalIdentifier:
|
|
twentyStandardFlatApplication.universalIdentifier,
|
|
},
|
|
),
|
|
this.messageQueueService.add<GenerateSdkClientJobData>(
|
|
GenerateSdkClientJob.name,
|
|
{
|
|
workspaceId,
|
|
applicationId: workspaceCustomFlatApplication.id,
|
|
applicationUniversalIdentifier:
|
|
workspaceCustomFlatApplication.universalIdentifier,
|
|
},
|
|
),
|
|
]);
|
|
|
|
await this.setupDefaultRoles({
|
|
workspaceId,
|
|
userId,
|
|
workspaceCustomFlatApplication,
|
|
});
|
|
}
|
|
|
|
private async setupDefaultRoles({
|
|
userId,
|
|
workspaceId,
|
|
workspaceCustomFlatApplication,
|
|
}: {
|
|
workspaceId: string;
|
|
userId: string;
|
|
workspaceCustomFlatApplication: FlatApplication;
|
|
}): Promise<void> {
|
|
const adminRole = await this.roleRepository.findOne({
|
|
where: {
|
|
universalIdentifier: STANDARD_ROLE.admin.universalIdentifier,
|
|
workspaceId,
|
|
},
|
|
});
|
|
|
|
if (adminRole) {
|
|
const userWorkspace = await this.userWorkspaceRepository.findOneOrFail({
|
|
where: { workspaceId, userId },
|
|
});
|
|
|
|
await this.userRoleService.assignRoleToManyUserWorkspace({
|
|
workspaceId,
|
|
userWorkspaceIds: [userWorkspace.id],
|
|
roleId: adminRole.id,
|
|
});
|
|
}
|
|
|
|
const memberRole = await this.roleService.createMemberRole({
|
|
workspaceId,
|
|
ownerFlatApplication: workspaceCustomFlatApplication,
|
|
});
|
|
|
|
await this.workspaceRepository.update(workspaceId, {
|
|
defaultRoleId: memberRole.id,
|
|
});
|
|
}
|
|
}
|