Add Tenant initialisation service (#2100)
* Add Tenant initialisation service * few fixes * fix constraint * fix tests * update metadata json with employees and address * add V2 * remove metadata.gql
This commit is contained in:
@ -0,0 +1,55 @@
|
||||
{
|
||||
"nameSingular": "companyV2",
|
||||
"namePlural": "companiesV2",
|
||||
"labelSingular": "Company",
|
||||
"labelPlural": "Companies",
|
||||
"targetTableName": "company",
|
||||
"description": "A company",
|
||||
"icon": "business",
|
||||
"fields": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "name",
|
||||
"label": "Name",
|
||||
"targetColumnMap": {
|
||||
"value": "name"
|
||||
},
|
||||
"description": "Name of the company",
|
||||
"icon": null,
|
||||
"isNullable": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "domainName",
|
||||
"label": "Domain Name",
|
||||
"targetColumnMap": {
|
||||
"value": "domainName"
|
||||
},
|
||||
"description": "Domain name of the company",
|
||||
"icon": "url",
|
||||
"isNullable": true
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "address",
|
||||
"label": "Address",
|
||||
"targetColumnMap": {
|
||||
"value": "address"
|
||||
},
|
||||
"description": "Address of the company",
|
||||
"icon": "location",
|
||||
"isNullable": true
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "employees",
|
||||
"label": "Employees",
|
||||
"targetColumnMap": {
|
||||
"value": "employees"
|
||||
},
|
||||
"description": "Number of employees",
|
||||
"icon": "people",
|
||||
"isNullable": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
import companyObject from './companies.metadata.json';
|
||||
|
||||
export const standardObjectsMetadata = {
|
||||
companyV2: companyObject,
|
||||
};
|
||||
@ -0,0 +1,24 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { DataSourceModule } from 'src/metadata/data-source/data-source.module';
|
||||
import { MigrationRunnerModule } from 'src/metadata/migration-runner/migration-runner.module';
|
||||
import { TenantMigrationModule } from 'src/metadata/tenant-migration/tenant-migration.module';
|
||||
import { FieldMetadataModule } from 'src/metadata/field-metadata/field-metadata.module';
|
||||
import { ObjectMetadataModule } from 'src/metadata/object-metadata/object-metadata.module';
|
||||
import { DataSourceMetadataModule } from 'src/metadata/data-source-metadata/data-source-metadata.module';
|
||||
|
||||
import { TenantInitialisationService } from './tenant-initialisation.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
DataSourceModule,
|
||||
TenantMigrationModule,
|
||||
MigrationRunnerModule,
|
||||
ObjectMetadataModule,
|
||||
FieldMetadataModule,
|
||||
DataSourceMetadataModule,
|
||||
],
|
||||
exports: [TenantInitialisationService],
|
||||
providers: [TenantInitialisationService],
|
||||
})
|
||||
export class TenantInitialisationModule {}
|
||||
@ -0,0 +1,93 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { TenantMigrationService } from 'src/metadata/tenant-migration/tenant-migration.service';
|
||||
import { MigrationRunnerService } from 'src/metadata/migration-runner/migration-runner.service';
|
||||
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
|
||||
import { FieldMetadataService } from 'src/metadata/field-metadata/services/field-metadata.service';
|
||||
import { ObjectMetadataService } from 'src/metadata/object-metadata/services/object-metadata.service';
|
||||
import { DataSourceMetadataService } from 'src/metadata/data-source-metadata/data-source-metadata.service';
|
||||
import { FieldMetadata } from 'src/metadata/field-metadata/field-metadata.entity';
|
||||
import { ObjectMetadata } from 'src/metadata/object-metadata/object-metadata.entity';
|
||||
|
||||
import { standardObjectsMetadata } from './standard-objects/standard-object-metadata';
|
||||
|
||||
@Injectable()
|
||||
export class TenantInitialisationService {
|
||||
constructor(
|
||||
private readonly dataSourceService: DataSourceService,
|
||||
private readonly tenantMigrationService: TenantMigrationService,
|
||||
private readonly migrationRunnerService: MigrationRunnerService,
|
||||
private readonly objectMetadataService: ObjectMetadataService,
|
||||
private readonly fieldMetadataService: FieldMetadataService,
|
||||
private readonly dataSourceMetadataService: DataSourceMetadataService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Init a workspace by creating a new data source and running all migrations
|
||||
* @param workspaceId
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
public async init(workspaceId: string): Promise<void> {
|
||||
const schemaName = await this.dataSourceService.createWorkspaceSchema(
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const dataSourceMetadata =
|
||||
await this.dataSourceMetadataService.createDataSourceMetadata(
|
||||
workspaceId,
|
||||
schemaName,
|
||||
);
|
||||
|
||||
await this.tenantMigrationService.insertStandardMigrations(workspaceId);
|
||||
|
||||
// Todo: keep in mind that we don't handle concurrency issues such as migrations being created at the same time
|
||||
// but it shouldn't be the role of this service to handle this kind of issues for now.
|
||||
// To check later when we run this in a job.
|
||||
await this.migrationRunnerService.executeMigrationFromPendingMigrations(
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
await this.createObjectsAndFieldsMetadata(
|
||||
dataSourceMetadata.id,
|
||||
workspaceId,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Create all standard objects and fields metadata for a given workspace
|
||||
*
|
||||
* @param dataSourceMetadataId
|
||||
* @param workspaceId
|
||||
*/
|
||||
private async createObjectsAndFieldsMetadata(
|
||||
dataSourceMetadataId: string,
|
||||
workspaceId: string,
|
||||
) {
|
||||
const createdObjectMetadata = await this.objectMetadataService.createMany(
|
||||
Object.values(standardObjectsMetadata).map((objectMetadata) => ({
|
||||
...objectMetadata,
|
||||
dataSourceId: dataSourceMetadataId,
|
||||
fields: [],
|
||||
workspaceId,
|
||||
isCustom: false,
|
||||
isActive: true,
|
||||
})),
|
||||
);
|
||||
|
||||
await this.fieldMetadataService.createMany(
|
||||
createdObjectMetadata.flatMap((objectMetadata: ObjectMetadata) =>
|
||||
standardObjectsMetadata[objectMetadata.nameSingular].fields.map(
|
||||
(field: FieldMetadata) => ({
|
||||
...field,
|
||||
objectId: objectMetadata.id,
|
||||
dataSourceId: dataSourceMetadataId,
|
||||
workspaceId,
|
||||
isCustom: false,
|
||||
isActive: true,
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user