Fix/metadata object and settings post merge (#2269)
* WIP * WIP2 * Seed views standard objects * Migrate views to the new data model --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
47
server/src/metadata/commands/data-seed-tenant.command.ts
Normal file
47
server/src/metadata/commands/data-seed-tenant.command.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { Command, CommandRunner, Option } from 'nest-commander';
|
||||
|
||||
import { TenantInitialisationService } from '../tenant-initialisation/tenant-initialisation.service';
|
||||
import { DataSourceMetadataService } from '../data-source-metadata/data-source-metadata.service';
|
||||
|
||||
// TODO: implement dry-run
|
||||
interface DataSeedTenantOptions {
|
||||
workspaceId: string;
|
||||
}
|
||||
|
||||
@Command({
|
||||
name: 'tenant:data-seed',
|
||||
description: 'Seed tenant with initial data',
|
||||
})
|
||||
export class DataSeedTenantCommand extends CommandRunner {
|
||||
constructor(
|
||||
private readonly dataSourceMetadataService: DataSourceMetadataService,
|
||||
private readonly tenantInitialisationService: TenantInitialisationService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async run(
|
||||
_passedParam: string[],
|
||||
options: DataSeedTenantOptions,
|
||||
): Promise<void> {
|
||||
const dataSourceMetadata =
|
||||
await this.dataSourceMetadataService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
||||
options.workspaceId,
|
||||
);
|
||||
// TODO: run in a dedicated job + run queries in a transaction.
|
||||
await this.tenantInitialisationService.prefillWorkspaceWithStandardObjects(
|
||||
dataSourceMetadata,
|
||||
options.workspaceId,
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: workspaceId should be optional and we should run migrations for all workspaces
|
||||
@Option({
|
||||
flags: '-w, --workspace-id [workspace_id]',
|
||||
description: 'workspace id',
|
||||
required: true,
|
||||
})
|
||||
parseWorkspaceId(value: string): string {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import { DataSourceMetadataModule } from 'src/metadata/data-source-metadata/data
|
||||
|
||||
import { SyncTenantMetadataCommand } from './sync-tenant-metadata.command';
|
||||
import { RunTenantMigrationsCommand } from './run-tenant-migrations.command';
|
||||
import { DataSeedTenantCommand } from './data-seed-tenant.command';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -19,6 +20,10 @@ import { RunTenantMigrationsCommand } from './run-tenant-migrations.command';
|
||||
DataSourceMetadataModule,
|
||||
TenantInitialisationModule,
|
||||
],
|
||||
providers: [RunTenantMigrationsCommand, SyncTenantMetadataCommand],
|
||||
providers: [
|
||||
RunTenantMigrationsCommand,
|
||||
SyncTenantMetadataCommand,
|
||||
DataSeedTenantCommand,
|
||||
],
|
||||
})
|
||||
export class MetadataCommandModule {}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Command, CommandRunner, Option } from 'nest-commander';
|
||||
|
||||
import { ObjectMetadataService } from 'src/metadata/object-metadata/services/object-metadata.service';
|
||||
import { FieldMetadataService } from 'src/metadata/field-metadata/services/field-metadata.service';
|
||||
import { TenantInitialisationService } from 'src/metadata/tenant-initialisation/tenant-initialisation.service';
|
||||
import { DataSourceMetadataService } from 'src/metadata/data-source-metadata/data-source-metadata.service';
|
||||
|
||||
@ -17,7 +16,6 @@ interface RunTenantMigrationsOptions {
|
||||
export class SyncTenantMetadataCommand extends CommandRunner {
|
||||
constructor(
|
||||
private readonly objectMetadataService: ObjectMetadataService,
|
||||
private readonly fieldMetadataService: FieldMetadataService,
|
||||
private readonly dataSourceMetadataService: DataSourceMetadataService,
|
||||
private readonly tenantInitialisationService: TenantInitialisationService,
|
||||
) {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
{
|
||||
"id": "1a8487a0-480c-434e-b4c7-e22408b97047",
|
||||
"nameSingular": "companyV2",
|
||||
"namePlural": "companiesV2",
|
||||
"labelSingular": "Company",
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
import companyObject from './companies/companies.metadata.json';
|
||||
import personObject from './people/people.metadata.json';
|
||||
import viewObject from './views/views.metadata.json';
|
||||
import viewFieldObject from './view-fields/view-fields.metadata.json';
|
||||
|
||||
export const standardObjectsMetadata = {
|
||||
companyV2: companyObject,
|
||||
personV2: personObject,
|
||||
viewV2: viewObject,
|
||||
viewFieldV2: viewFieldObject,
|
||||
};
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
import companySeeds from './companies/companies.seeds.json';
|
||||
import viewSeeds from './views/views.seeds.json';
|
||||
import viewFieldSeeds from './view-fields/view-fields.seeds.json';
|
||||
|
||||
export const standardObjectsSeeds = {
|
||||
companyV2: companySeeds,
|
||||
viewV2: viewSeeds,
|
||||
viewFieldV2: viewFieldSeeds,
|
||||
};
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
{
|
||||
"nameSingular": "viewFieldV2",
|
||||
"namePlural": "viewFieldsV2",
|
||||
"labelSingular": "View Field",
|
||||
"labelPlural": "View Fields",
|
||||
"targetTableName": "viewField",
|
||||
"description": "(System) View Fields",
|
||||
"icon": "arrows-sort",
|
||||
"fields": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "objectId",
|
||||
"label": "Object Id",
|
||||
"targetColumnMap": {
|
||||
"value": "objectId"
|
||||
},
|
||||
"description": "View Field target object",
|
||||
"icon": null,
|
||||
"isNullable": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "fieldId",
|
||||
"label": "Field Id",
|
||||
"targetColumnMap": {
|
||||
"value": "fieldId"
|
||||
},
|
||||
"description": "View Field target field",
|
||||
"icon": null,
|
||||
"isNullable": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "viewId",
|
||||
"label": "View Id",
|
||||
"targetColumnMap": {
|
||||
"value": "viewId"
|
||||
},
|
||||
"description": "View Field related view",
|
||||
"icon": null,
|
||||
"isNullable": false
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"name": "isVisible",
|
||||
"label": "Visible",
|
||||
"targetColumnMap": {
|
||||
"value": "isVisible"
|
||||
},
|
||||
"description": "View Field visibility",
|
||||
"icon": null,
|
||||
"isNullable": false
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "size",
|
||||
"label": "Size",
|
||||
"targetColumnMap": {
|
||||
"value": "size"
|
||||
},
|
||||
"description": "View Field size",
|
||||
"icon": null,
|
||||
"isNullable": false
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"name": "position",
|
||||
"label": "Position",
|
||||
"targetColumnMap": {
|
||||
"value": "position"
|
||||
},
|
||||
"description": "View Field position",
|
||||
"icon": null,
|
||||
"isNullable": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
[
|
||||
{
|
||||
"objectId": "1a8487a0-480c-434e-b4c7-e22408b97047",
|
||||
"fieldId": "name",
|
||||
"viewId": "10bec73c-0aea-4cc4-a3b2-8c2186f29b43",
|
||||
"position": 0,
|
||||
"isVisible": true,
|
||||
"size": 180
|
||||
},
|
||||
|
||||
{
|
||||
"objectId": "company",
|
||||
"fieldId": "name",
|
||||
"viewId": "37a8a866-eb17-4e76-9382-03143a2f6a80",
|
||||
"position": 0,
|
||||
"isVisible": true,
|
||||
"size": 180
|
||||
},
|
||||
{
|
||||
"objectId": "company",
|
||||
"fieldId": "domainName",
|
||||
"viewId": "37a8a866-eb17-4e76-9382-03143a2f6a80",
|
||||
"position": 1,
|
||||
"isVisible": true,
|
||||
"size": 100
|
||||
},
|
||||
{
|
||||
"objectId": "company",
|
||||
"fieldId": "accountOwner",
|
||||
"viewId": "37a8a866-eb17-4e76-9382-03143a2f6a80",
|
||||
"position": 2,
|
||||
"isVisible": true,
|
||||
"size": 150
|
||||
},
|
||||
{
|
||||
"objectId": "company",
|
||||
"fieldId": "createdAt",
|
||||
"viewId": "37a8a866-eb17-4e76-9382-03143a2f6a80",
|
||||
"position": 3,
|
||||
"isVisible": true,
|
||||
"size": 150
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,44 @@
|
||||
{
|
||||
"nameSingular": "viewV2",
|
||||
"namePlural": "viewsV2",
|
||||
"labelSingular": "View",
|
||||
"labelPlural": "Views",
|
||||
"targetTableName": "view",
|
||||
"description": "(System) Views",
|
||||
"icon": "layout-collage",
|
||||
"fields": [
|
||||
{
|
||||
"type": "text",
|
||||
"name": "name",
|
||||
"label": "Name",
|
||||
"targetColumnMap": {
|
||||
"value": "name"
|
||||
},
|
||||
"description": "View name",
|
||||
"icon": null,
|
||||
"isNullable": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "objectId",
|
||||
"label": "Object Id",
|
||||
"targetColumnMap": {
|
||||
"value": "objectId"
|
||||
},
|
||||
"description": "View target object",
|
||||
"icon": null,
|
||||
"isNullable": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"name": "type",
|
||||
"label": "Type",
|
||||
"targetColumnMap": {
|
||||
"value": "type"
|
||||
},
|
||||
"description": "View type",
|
||||
"icon": null,
|
||||
"isNullable": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"id": "37a8a866-eb17-4e76-9382-03143a2f6a80",
|
||||
"name": "All companies",
|
||||
"objectId": "company",
|
||||
"type": "Table"
|
||||
},
|
||||
{
|
||||
"id": "6095799e-b48f-4e00-b071-10818083593a",
|
||||
"name": "All companies",
|
||||
"objectId": "person",
|
||||
"type": "Table"
|
||||
},
|
||||
{
|
||||
"id": "e26f66b7-f890-4a5c-b4d2-ec09987b5308",
|
||||
"name": "All Opportunities",
|
||||
"objectId": "company",
|
||||
"type": "Pipeline"
|
||||
},
|
||||
{
|
||||
"id": "10bec73c-0aea-4cc4-a3b2-8c2186f29b43",
|
||||
"name": "All Companies (V2)",
|
||||
"objectId": "1a8487a0-480c-434e-b4c7-e22408b97047",
|
||||
"type": "Table"
|
||||
}
|
||||
]
|
||||
@ -98,7 +98,7 @@ export class TenantInitialisationService {
|
||||
);
|
||||
}
|
||||
|
||||
private async prefillWorkspaceWithStandardObjects(
|
||||
public async prefillWorkspaceWithStandardObjects(
|
||||
dataSourceMetadata: DataSourceMetadata,
|
||||
workspaceId: string,
|
||||
) {
|
||||
@ -117,11 +117,7 @@ export class TenantInitialisationService {
|
||||
continue;
|
||||
}
|
||||
|
||||
const fields = standardObjectsMetadata[object.nameSingular].fields;
|
||||
|
||||
const columns = fields.map((field: FieldMetadata) =>
|
||||
Object.values(field.targetColumnMap),
|
||||
);
|
||||
const columns = Object.keys(seedData[0]);
|
||||
|
||||
await workspaceDataSource
|
||||
?.createQueryBuilder()
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
import { TenantMigrationTableAction } from 'src/metadata/tenant-migration/tenant-migration.entity';
|
||||
|
||||
export const addViewTable: TenantMigrationTableAction[] = [
|
||||
{
|
||||
name: 'view',
|
||||
action: 'create',
|
||||
},
|
||||
{
|
||||
name: 'view',
|
||||
action: 'alter',
|
||||
columns: [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'varchar',
|
||||
action: 'create',
|
||||
},
|
||||
{
|
||||
name: 'objectId',
|
||||
type: 'varchar',
|
||||
action: 'create',
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
type: 'varchar',
|
||||
action: 'create',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@ -0,0 +1,44 @@
|
||||
import { TenantMigrationTableAction } from 'src/metadata/tenant-migration/tenant-migration.entity';
|
||||
|
||||
export const addViewFieldTable: TenantMigrationTableAction[] = [
|
||||
{
|
||||
name: 'viewField',
|
||||
action: 'create',
|
||||
},
|
||||
{
|
||||
name: 'viewField',
|
||||
action: 'alter',
|
||||
columns: [
|
||||
{
|
||||
name: 'objectId',
|
||||
type: 'varchar',
|
||||
action: 'create',
|
||||
},
|
||||
{
|
||||
name: 'fieldId',
|
||||
type: 'varchar',
|
||||
action: 'create',
|
||||
},
|
||||
{
|
||||
name: 'viewId',
|
||||
type: 'varchar',
|
||||
action: 'create',
|
||||
},
|
||||
{
|
||||
name: 'position',
|
||||
type: 'integer',
|
||||
action: 'create',
|
||||
},
|
||||
{
|
||||
name: 'isVisible',
|
||||
type: 'boolean',
|
||||
action: 'create',
|
||||
},
|
||||
{
|
||||
name: 'size',
|
||||
type: 'integer',
|
||||
action: 'create',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@ -1,8 +1,12 @@
|
||||
import { addCompanyTable } from './migrations/1697618009-addCompanyTable';
|
||||
import { addPeopleTable } from './migrations/1697618010-addPeopleTable';
|
||||
import { addViewTable } from './migrations/1697618011-addViewTable';
|
||||
import { addViewFieldTable } from './migrations/1697618012-addViewFieldTable';
|
||||
|
||||
// TODO: read the folder and return all migrations
|
||||
export const standardMigrations = {
|
||||
'1697618009-addCompanyTable': addCompanyTable,
|
||||
'1697618010-addPeopleTable': addPeopleTable,
|
||||
'1697618011-addViewTable': addViewTable,
|
||||
'1697618012-addViewFieldTable': addViewFieldTable,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user