diff --git a/server/src/metadata/args/create-custom-field.input.ts b/server/src/metadata/args/create-custom-field.input.ts index 93e24f452..14da4109a 100644 --- a/server/src/metadata/args/create-custom-field.input.ts +++ b/server/src/metadata/args/create-custom-field.input.ts @@ -7,7 +7,7 @@ export class CreateCustomFieldInput { @Field(() => String) @IsNotEmpty() @IsString() - name: string; + displayName: string; @Field(() => String) @IsNotEmpty() diff --git a/server/src/metadata/data-source/data-source.module.ts b/server/src/metadata/data-source/data-source.module.ts index f2641a772..48cd14143 100644 --- a/server/src/metadata/data-source/data-source.module.ts +++ b/server/src/metadata/data-source/data-source.module.ts @@ -1,12 +1,11 @@ import { Module } from '@nestjs/common'; import { DataSourceMetadataModule } from 'src/metadata/data-source-metadata/data-source-metadata.module'; -import { EntitySchemaGeneratorModule } from 'src/metadata/entity-schema-generator/entity-schema-generator.module'; import { DataSourceService } from './data-source.service'; @Module({ - imports: [DataSourceMetadataModule, EntitySchemaGeneratorModule], + imports: [DataSourceMetadataModule], providers: [DataSourceService], exports: [DataSourceService], }) diff --git a/server/src/metadata/data-source/data-source.service.spec.ts b/server/src/metadata/data-source/data-source.service.spec.ts index f1912eff6..a4026407f 100644 --- a/server/src/metadata/data-source/data-source.service.spec.ts +++ b/server/src/metadata/data-source/data-source.service.spec.ts @@ -2,7 +2,6 @@ import { Test, TestingModule } from '@nestjs/testing'; import { EnvironmentService } from 'src/integrations/environment/environment.service'; import { DataSourceMetadataService } from 'src/metadata/data-source-metadata/data-source-metadata.service'; -import { EntitySchemaGeneratorService } from 'src/metadata/entity-schema-generator/entity-schema-generator.service'; import { DataSourceService } from './data-source.service'; @@ -23,10 +22,6 @@ describe('DataSourceService', () => { provide: DataSourceMetadataService, useValue: {}, }, - { - provide: EntitySchemaGeneratorService, - useValue: {}, - }, ], }).compile(); diff --git a/server/src/metadata/data-source/data-source.service.ts b/server/src/metadata/data-source/data-source.service.ts index 74412143a..5db3a800a 100644 --- a/server/src/metadata/data-source/data-source.service.ts +++ b/server/src/metadata/data-source/data-source.service.ts @@ -4,7 +4,6 @@ import { DataSource, QueryRunner, Table } from 'typeorm'; import { EnvironmentService } from 'src/integrations/environment/environment.service'; import { DataSourceMetadataService } from 'src/metadata/data-source-metadata/data-source-metadata.service'; -import { EntitySchemaGeneratorService } from 'src/metadata/entity-schema-generator/entity-schema-generator.service'; import { TenantMigration } from 'src/metadata/tenant-migration/tenant-migration.entity'; import { uuidToBase36 } from './data-source.util'; @@ -17,7 +16,6 @@ export class DataSourceService implements OnModuleInit, OnModuleDestroy { constructor( private readonly environmentService: EnvironmentService, private readonly dataSourceMetadataService: DataSourceMetadataService, - private readonly entitySchemaGeneratorService: EntitySchemaGeneratorService, ) { this.mainDataSource = new DataSource({ url: environmentService.getPGDatabaseUrl(), diff --git a/server/src/metadata/entity-schema-generator/base.entity.ts b/server/src/metadata/entity-schema-generator/base.entity.ts deleted file mode 100644 index 46a7cbdeb..000000000 --- a/server/src/metadata/entity-schema-generator/base.entity.ts +++ /dev/null @@ -1,15 +0,0 @@ -export const baseColumns = { - id: { - primary: true, - type: 'uuid', - generated: 'uuid', - }, - createdAt: { - type: 'timestamp', - createDate: true, - }, - updatedAt: { - type: 'timestamp', - updateDate: true, - }, -} as const; diff --git a/server/src/metadata/entity-schema-generator/entity-schema-generator.module.ts b/server/src/metadata/entity-schema-generator/entity-schema-generator.module.ts deleted file mode 100644 index 65767de0b..000000000 --- a/server/src/metadata/entity-schema-generator/entity-schema-generator.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { ObjectMetadataModule } from 'src/metadata/object-metadata/object-metadata.module'; - -import { EntitySchemaGeneratorService } from './entity-schema-generator.service'; - -@Module({ - imports: [ObjectMetadataModule], - providers: [EntitySchemaGeneratorService], - exports: [EntitySchemaGeneratorService], -}) -export class EntitySchemaGeneratorModule {} diff --git a/server/src/metadata/entity-schema-generator/entity-schema-generator.service.spec.ts b/server/src/metadata/entity-schema-generator/entity-schema-generator.service.spec.ts deleted file mode 100644 index 2ecbfa043..000000000 --- a/server/src/metadata/entity-schema-generator/entity-schema-generator.service.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; - -import { ObjectMetadataService } from 'src/metadata/object-metadata/object-metadata.service'; - -import { EntitySchemaGeneratorService } from './entity-schema-generator.service'; - -describe('EntitySchemaGeneratorService', () => { - let service: EntitySchemaGeneratorService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ - EntitySchemaGeneratorService, - { - provide: ObjectMetadataService, - useValue: {}, - }, - ], - }).compile(); - - service = module.get( - EntitySchemaGeneratorService, - ); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/server/src/metadata/entity-schema-generator/entity-schema-generator.service.ts b/server/src/metadata/entity-schema-generator/entity-schema-generator.service.ts deleted file mode 100644 index 75067db79..000000000 --- a/server/src/metadata/entity-schema-generator/entity-schema-generator.service.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { EntitySchema } from 'typeorm'; - -import { ObjectMetadataService } from 'src/metadata/object-metadata/object-metadata.service'; - -import { baseColumns } from './base.entity'; -import { - convertFieldTypeToPostgresType, - sanitizeColumnName, -} from './entity-schema-generator.util'; - -@Injectable() -export class EntitySchemaGeneratorService { - constructor(private readonly objectMetadataService: ObjectMetadataService) {} - - async getTypeORMEntitiesByDataSourceId(dataSourceId: string) { - const objectMetadata = - await this.objectMetadataService.getObjectMetadataFromDataSourceId( - dataSourceId, - ); - - const entities = objectMetadata.map((object) => { - return new EntitySchema({ - name: object.targetTableName, - columns: { - ...baseColumns, - ...object.fields.reduce((columns, field) => { - return { - ...columns, - [sanitizeColumnName(field.targetColumnName)]: { - type: convertFieldTypeToPostgresType(field.type), - nullable: true, - }, - }; - }, {}), - }, - }); - }); - - return entities; - } -} diff --git a/server/src/metadata/entity-schema-generator/entity-schema-generator.util.ts b/server/src/metadata/entity-schema-generator/entity-schema-generator.util.ts deleted file mode 100644 index 9c1687377..000000000 --- a/server/src/metadata/entity-schema-generator/entity-schema-generator.util.ts +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Converts a UUID to a base 36 string. - * This is used to generate the schema name since hyphens from workspace uuid are not allowed in postgres schema names. - * - * @param uuid - * @returns - */ -export const uuidToBase36 = (uuid: string): string => { - const hexString = uuid.replace(/-/g, ''); - const base10Number = BigInt('0x' + hexString); - const base36String = base10Number.toString(36); - return base36String; -}; - -/** - * Sanitizes a column name by replacing all non-alphanumeric characters with an underscore. - * Note: Probablay not the best way to do this, leaving it here as a placeholder for now. - * - * @param columnName - * @returns string - */ -export const sanitizeColumnName = (columnName: string): string => - columnName.replace(/[^a-zA-Z0-9]/g, '_'); - -/** - * Converts a field type to a postgres type. Field types are defined in the UI. - * - * @param fieldType - * @returns string - */ -export const convertFieldTypeToPostgresType = (fieldType: string): string => { - switch (fieldType) { - case 'text': - case 'url': - return 'text'; - case 'number': - return 'numeric'; - case 'boolean': - return 'boolean'; - case 'date': - return 'timestamp'; - default: - return 'text'; - } -}; diff --git a/server/src/metadata/field-metadata/field-metadata.entity.ts b/server/src/metadata/field-metadata/field-metadata.entity.ts index 7bafe0537..4578bbb04 100644 --- a/server/src/metadata/field-metadata/field-metadata.entity.ts +++ b/server/src/metadata/field-metadata/field-metadata.entity.ts @@ -10,6 +10,10 @@ import { import { ObjectMetadata } from 'src/metadata/object-metadata/object-metadata.entity'; +export type FieldMetadataTargetColumnMap = { + [key: string]: string; +}; + @Entity('field_metadata') export class FieldMetadata { @PrimaryGeneratedColumn('uuid') @@ -27,12 +31,27 @@ export class FieldMetadata { @Column({ nullable: false, name: 'target_column_name' }) targetColumnName: string; + @Column({ nullable: true, name: 'description', type: 'text' }) + description: string; + + @Column({ nullable: true, name: 'icon' }) + icon: string; + + @Column({ nullable: true, name: 'placeholder' }) + placeholder: string; + + @Column({ nullable: true, name: 'target_column_map', type: 'jsonb' }) + targetColumnMap: FieldMetadataTargetColumnMap; + @Column('text', { nullable: true, array: true }) enums: string[]; @Column({ default: false, name: 'is_custom' }) isCustom: boolean; + @Column({ default: false, name: 'is_active' }) + isActive: boolean; + @Column({ nullable: true, default: true, name: 'is_nullable' }) isNullable: boolean; diff --git a/server/src/metadata/field-metadata/field-metadata.service.ts b/server/src/metadata/field-metadata/field-metadata.service.ts index aa0c4cd14..87a0d652c 100644 --- a/server/src/metadata/field-metadata/field-metadata.service.ts +++ b/server/src/metadata/field-metadata/field-metadata.service.ts @@ -4,7 +4,10 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { FieldMetadata } from './field-metadata.entity'; -import { generateColumnName } from './field-metadata.util'; +import { + generateColumnName, + generateTargetColumnMap, +} from './field-metadata.util'; @Injectable() export class FieldMetadataService { @@ -14,22 +17,23 @@ export class FieldMetadataService { ) {} public async createFieldMetadata( - name: string, + displayName: string, type: string, objectId: string, workspaceId: string, ): Promise { return await this.fieldMetadataRepository.save({ - displayName: name, + displayName: displayName, type, objectId, isCustom: true, - targetColumnName: generateColumnName(name), + targetColumnName: generateColumnName(displayName), // deprecated workspaceId, + targetColumnMap: generateTargetColumnMap(type), }); } - public async getFieldMetadataByNameAndObjectId( + public async getFieldMetadataByDisplayNameAndObjectId( name: string, objectId: string, ): Promise { diff --git a/server/src/metadata/field-metadata/field-metadata.util.ts b/server/src/metadata/field-metadata/field-metadata.util.ts index 635e7fe64..b5eb8c84f 100644 --- a/server/src/metadata/field-metadata/field-metadata.util.ts +++ b/server/src/metadata/field-metadata/field-metadata.util.ts @@ -1,3 +1,9 @@ +import { v4 } from 'uuid'; + +import { uuidToBase36 } from 'src/metadata/data-source/data-source.util'; + +import { FieldMetadataTargetColumnMap } from './field-metadata.entity'; + /** * Generate a column name from a field name removing unsupported characters. * @@ -7,3 +13,38 @@ export function generateColumnName(name: string): string { return name.toLowerCase().replace(/ /g, '_'); } + +/** + * Generate a target column map for a given type, this is used to map the field to the correct column(s) in the database. + * This is used to support fields that map to multiple columns in the database. + * + * @param type string + * @returns FieldMetadataTargetColumnMap + */ +export function generateTargetColumnMap( + type: string, +): FieldMetadataTargetColumnMap { + switch (type) { + case 'text': + case 'phone': + case 'email': + case 'number': + case 'boolean': + case 'date': + return { + value: uuidToBase36(v4()), + }; + case 'url': + return { + text: uuidToBase36(v4()), + link: uuidToBase36(v4()), + }; + case 'money': + return { + amount: uuidToBase36(v4()), + currency: uuidToBase36(v4()), + }; + default: + throw new Error(`Unknown type ${type}`); + } +} diff --git a/server/src/metadata/metadata.controller.spec.ts b/server/src/metadata/metadata.controller.spec.ts deleted file mode 100644 index 68e9e0917..000000000 --- a/server/src/metadata/metadata.controller.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; - -import { MetadataController } from './metadata.controller'; - -import { DataSourceService } from './data-source/data-source.service'; -import { DataSourceMetadataService } from './data-source-metadata/data-source-metadata.service'; -import { EntitySchemaGeneratorService } from './entity-schema-generator/entity-schema-generator.service'; -import { MigrationGeneratorService } from './migration-generator/migration-generator.service'; - -describe('MetadataController', () => { - let controller: MetadataController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [MetadataController], - providers: [ - { - provide: DataSourceService, - useValue: {}, - }, - { - provide: DataSourceMetadataService, - useValue: {}, - }, - { - provide: EntitySchemaGeneratorService, - useValue: {}, - }, - { - provide: MigrationGeneratorService, - useValue: {}, - }, - ], - }).compile(); - - controller = module.get(MetadataController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/server/src/metadata/metadata.controller.ts b/server/src/metadata/metadata.controller.ts deleted file mode 100644 index 5ebb045d2..000000000 --- a/server/src/metadata/metadata.controller.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Controller, Get, UseGuards } from '@nestjs/common'; - -import { Workspace } from '@prisma/client'; -import { EntitySchema } from 'typeorm'; - -import { AuthWorkspace } from 'src/decorators/auth-workspace.decorator'; -import { JwtAuthGuard } from 'src/guards/jwt.auth.guard'; - -import { DataSourceMetadataService } from './data-source-metadata/data-source-metadata.service'; -import { EntitySchemaGeneratorService } from './entity-schema-generator/entity-schema-generator.service'; -import { DataSourceService } from './data-source/data-source.service'; -import { MigrationGeneratorService } from './migration-generator/migration-generator.service'; - -@UseGuards(JwtAuthGuard) -@Controller('metadata_legacy') -export class MetadataController { - constructor( - private readonly entitySchemaGeneratorService: EntitySchemaGeneratorService, - private readonly dataSourceMetadataService: DataSourceMetadataService, - private readonly dataSourceService: DataSourceService, - private readonly migrationGenerator: MigrationGeneratorService, - ) {} - - @Get() - async getMetadata(@AuthWorkspace() workspace: Workspace) { - const dataSourcesMetadata = - await this.dataSourceMetadataService.getDataSourcesMetadataFromWorkspaceId( - workspace.id, - ); - - const entities: EntitySchema<{ - id: unknown; - }>[] = []; - - for (const dataSource of dataSourcesMetadata) { - const dataSourceEntities = - await this.entitySchemaGeneratorService.getTypeORMEntitiesByDataSourceId( - dataSource.id, - ); - - entities.push(...dataSourceEntities); - } - - this.dataSourceService.createWorkspaceSchema(workspace.id); - - await this.migrationGenerator.executeMigrationFromPendingMigrations( - workspace.id, - ); - - this.dataSourceService.connectToWorkspaceDataSource(workspace.id); - - return entities; - } -} diff --git a/server/src/metadata/metadata.module.ts b/server/src/metadata/metadata.module.ts index 86b334965..26e8da807 100644 --- a/server/src/metadata/metadata.module.ts +++ b/server/src/metadata/metadata.module.ts @@ -5,8 +5,10 @@ import { GraphQLModule } from '@nestjs/graphql'; import { YogaDriverConfig, YogaDriver } from '@graphql-yoga/nestjs'; import GraphQLJSON from 'graphql-type-json'; +import { MigrationGeneratorModule } from 'src/metadata/migration-generator/migration-generator.module'; +import { TenantMigrationModule } from 'src/metadata/tenant-migration/tenant-migration.module'; + import { MetadataService } from './metadata.service'; -import { MetadataController } from './metadata.controller'; import { typeORMMetadataModuleOptions } from './metadata.datasource'; import { MetadataResolver } from './metadata.resolver'; @@ -14,9 +16,6 @@ import { DataSourceModule } from './data-source/data-source.module'; import { DataSourceMetadataModule } from './data-source-metadata/data-source-metadata.module'; import { FieldMetadataModule } from './field-metadata/field-metadata.module'; import { ObjectMetadataModule } from './object-metadata/object-metadata.module'; -import { EntitySchemaGeneratorModule } from './entity-schema-generator/entity-schema-generator.module'; -import { MigrationGeneratorModule } from './migration-generator/migration-generator.module'; -import { TenantMigrationModule } from './tenant-migration/tenant-migration.module'; const typeORMFactory = async (): Promise => ({ ...typeORMMetadataModuleOptions, @@ -42,12 +41,10 @@ const typeORMFactory = async (): Promise => ({ DataSourceMetadataModule, FieldMetadataModule, ObjectMetadataModule, - EntitySchemaGeneratorModule, MigrationGeneratorModule, TenantMigrationModule, ], providers: [MetadataService, MetadataResolver], exports: [MetadataService], - controllers: [MetadataController], }) export class MetadataModule {} diff --git a/server/src/metadata/metadata.resolver.ts b/server/src/metadata/metadata.resolver.ts index 4a64a6545..22c5de6bc 100644 --- a/server/src/metadata/metadata.resolver.ts +++ b/server/src/metadata/metadata.resolver.ts @@ -26,7 +26,7 @@ export class MetadataResolver { @AuthWorkspace() workspace: Workspace, ): Promise { return this.metadataService.createCustomField( - createCustomFieldInput.name, + createCustomFieldInput.displayName, createCustomFieldInput.objectId, createCustomFieldInput.type, workspace.id, diff --git a/server/src/metadata/metadata.service.spec.ts b/server/src/metadata/metadata.service.spec.ts index af3ad60ad..d2ebe7043 100644 --- a/server/src/metadata/metadata.service.spec.ts +++ b/server/src/metadata/metadata.service.spec.ts @@ -1,11 +1,12 @@ import { Test, TestingModule } from '@nestjs/testing'; +import { MigrationGeneratorService } from 'src/metadata/migration-generator/migration-generator.service'; +import { TenantMigrationService } from 'src/metadata/tenant-migration/tenant-migration.service'; + import { MetadataService } from './metadata.service'; -import { MigrationGeneratorService } from './migration-generator/migration-generator.service'; import { DataSourceService } from './data-source/data-source.service'; import { ObjectMetadataService } from './object-metadata/object-metadata.service'; -import { TenantMigrationService } from './tenant-migration/tenant-migration.service'; import { FieldMetadataService } from './field-metadata/field-metadata.service'; describe('MetadataService', () => { diff --git a/server/src/metadata/metadata.service.ts b/server/src/metadata/metadata.service.ts index 8625c6631..0d4b87d08 100644 --- a/server/src/metadata/metadata.service.ts +++ b/server/src/metadata/metadata.service.ts @@ -1,14 +1,17 @@ import { Injectable } from '@nestjs/common'; -import { DataSourceService } from './data-source/data-source.service'; -import { FieldMetadataService } from './field-metadata/field-metadata.service'; -import { MigrationGeneratorService } from './migration-generator/migration-generator.service'; -import { ObjectMetadataService } from './object-metadata/object-metadata.service'; -import { TenantMigrationService } from './tenant-migration/tenant-migration.service'; +import { MigrationGeneratorService } from 'src/metadata/migration-generator/migration-generator.service'; +import { TenantMigrationService } from 'src/metadata/tenant-migration/tenant-migration.service'; import { TenantMigrationColumnChange, TenantMigrationTableChange, -} from './tenant-migration/tenant-migration.entity'; +} from 'src/metadata/tenant-migration/tenant-migration.entity'; + +import { convertFieldMetadataToColumnChanges } from './metadata.util'; + +import { DataSourceService } from './data-source/data-source.service'; +import { FieldMetadataService } from './field-metadata/field-metadata.service'; +import { ObjectMetadataService } from './object-metadata/object-metadata.service'; @Injectable() export class MetadataService { @@ -21,7 +24,7 @@ export class MetadataService { ) {} public async createCustomField( - name: string, + displayName: string, objectId: string, type: string, workspaceId: string, @@ -41,8 +44,8 @@ export class MetadataService { } const fieldMetadataAlreadyExists = - await this.fieldMetadataService.getFieldMetadataByNameAndObjectId( - name, + await this.fieldMetadataService.getFieldMetadataByDisplayNameAndObjectId( + displayName, objectId, ); @@ -52,7 +55,7 @@ export class MetadataService { const createdFieldMetadata = await this.fieldMetadataService.createFieldMetadata( - name, + displayName, type, objectMetadata.id, workspaceId, @@ -63,6 +66,8 @@ export class MetadataService { name: objectMetadata.targetTableName, change: 'alter', columns: [ + ...convertFieldMetadataToColumnChanges(createdFieldMetadata), + // Deprecated { name: createdFieldMetadata.targetColumnName, type: this.convertMetadataTypeToColumnType(type), @@ -79,6 +84,7 @@ export class MetadataService { return createdFieldMetadata.id; } + // Deprecated with target_column_name private convertMetadataTypeToColumnType(type: string) { switch (type) { case 'text': @@ -92,6 +98,8 @@ export class MetadataService { return 'boolean'; case 'date': return 'timestamp'; + case 'money': + return 'integer'; default: throw new Error('Invalid type'); } diff --git a/server/src/metadata/metadata.util.ts b/server/src/metadata/metadata.util.ts new file mode 100644 index 000000000..e80d2ffe3 --- /dev/null +++ b/server/src/metadata/metadata.util.ts @@ -0,0 +1,79 @@ +import { TenantMigrationColumnChange } from 'src/metadata/tenant-migration/tenant-migration.entity'; + +import { FieldMetadata } from './field-metadata/field-metadata.entity'; + +export function convertFieldMetadataToColumnChanges( + fieldMetadata: FieldMetadata, +): TenantMigrationColumnChange[] { + switch (fieldMetadata.type) { + case 'text': + return [ + { + name: fieldMetadata.targetColumnMap.value, + change: 'create', + type: 'text', + }, + ]; + case 'phone': + case 'email': + return [ + { + name: fieldMetadata.targetColumnMap.value, + change: 'create', + type: 'varchar', + }, + ]; + case 'number': + return [ + { + name: fieldMetadata.targetColumnMap.value, + change: 'create', + type: 'integer', + }, + ]; + case 'boolean': + return [ + { + name: fieldMetadata.targetColumnMap.value, + change: 'create', + type: 'boolean', + }, + ]; + case 'date': + return [ + { + name: fieldMetadata.targetColumnMap.value, + change: 'create', + type: 'timestamp', + }, + ]; + case 'url': + return [ + { + name: fieldMetadata.targetColumnMap.text, + change: 'create', + type: 'varchar', + }, + { + name: fieldMetadata.targetColumnMap.link, + change: 'create', + type: 'varchar', + }, + ]; + case 'money': + return [ + { + name: fieldMetadata.targetColumnMap.amount, + change: 'create', + type: 'integer', + }, + { + name: fieldMetadata.targetColumnMap.currency, + change: 'create', + type: 'varchar', + }, + ]; + default: + throw new Error(`Unknown type ${fieldMetadata.type}`); + } +} diff --git a/server/src/metadata/migrations/1696409050890-add-target-column-map.ts b/server/src/metadata/migrations/1696409050890-add-target-column-map.ts new file mode 100644 index 000000000..23da21eb0 --- /dev/null +++ b/server/src/metadata/migrations/1696409050890-add-target-column-map.ts @@ -0,0 +1,71 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddTargetColumnMap1696409050890 implements MigrationInterface { + name = 'AddTargetColumnMap1696409050890'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "metadata"."field_metadata" ADD "description" text`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."field_metadata" ADD "icon" character varying`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."field_metadata" ADD "placeholder" character varying`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."field_metadata" ADD "target_column_map" jsonb`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."field_metadata" ADD "is_active" boolean NOT NULL DEFAULT false`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."object_metadata" ADD "display_name_singular" character varying`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."object_metadata" ADD "display_name_plural" character varying`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."object_metadata" ADD "description" text`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."object_metadata" ADD "icon" character varying`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."object_metadata" ADD "is_active" boolean NOT NULL DEFAULT false`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "metadata"."object_metadata" DROP COLUMN "is_active"`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."object_metadata" DROP COLUMN "icon"`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."object_metadata" DROP COLUMN "description"`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."object_metadata" DROP COLUMN "display_name_plural"`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."object_metadata" DROP COLUMN "display_name_singular"`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."field_metadata" DROP COLUMN "is_active"`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."field_metadata" DROP COLUMN "target_column_map"`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."field_metadata" DROP COLUMN "placeholder"`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."field_metadata" DROP COLUMN "icon"`, + ); + await queryRunner.query( + `ALTER TABLE "metadata"."field_metadata" DROP COLUMN "description"`, + ); + } +} diff --git a/server/src/metadata/object-metadata/object-metadata.entity.ts b/server/src/metadata/object-metadata/object-metadata.entity.ts index 49ca92973..d93e16537 100644 --- a/server/src/metadata/object-metadata/object-metadata.entity.ts +++ b/server/src/metadata/object-metadata/object-metadata.entity.ts @@ -17,15 +17,31 @@ export class ObjectMetadata { @Column({ nullable: false, name: 'data_source_id' }) dataSourceId: string; + // Deprecated @Column({ nullable: false, name: 'display_name' }) displayName: string; + @Column({ nullable: true, name: 'display_name_singular' }) + displayNameSingular: string; + + @Column({ nullable: true, name: 'display_name_plural' }) + displayNamePlural: string; + + @Column({ nullable: true, name: 'description', type: 'text' }) + description: string; + + @Column({ nullable: true, name: 'icon' }) + icon: string; + @Column({ nullable: false, name: 'target_table_name' }) targetTableName: string; @Column({ default: false, name: 'is_custom' }) isCustom: boolean; + @Column({ default: false, name: 'is_active' }) + isActive: boolean; + @Column({ nullable: false, name: 'workspace_id' }) workspaceId: string; diff --git a/server/src/tenant/schema-generation/schema-generation.module.ts b/server/src/tenant/schema-generation/schema-generation.module.ts index 37099884b..e2709cdc9 100644 --- a/server/src/tenant/schema-generation/schema-generation.module.ts +++ b/server/src/tenant/schema-generation/schema-generation.module.ts @@ -3,7 +3,6 @@ import { Module } from '@nestjs/common'; import { EntityResolverModule } from 'src/tenant/entity-resolver/entity-resolver.module'; import { JwtAuthGuard } from 'src/guards/jwt.auth.guard'; import { DataSourceMetadataModule } from 'src/metadata/data-source-metadata/data-source-metadata.module'; -import { EntitySchemaGeneratorModule } from 'src/metadata/entity-schema-generator/entity-schema-generator.module'; import { ObjectMetadataModule } from 'src/metadata/object-metadata/object-metadata.module'; import { SchemaGenerationService } from './schema-generation.service'; @@ -12,7 +11,6 @@ import { SchemaGenerationService } from './schema-generation.service'; imports: [ EntityResolverModule, DataSourceMetadataModule, - EntitySchemaGeneratorModule, ObjectMetadataModule, ], providers: [SchemaGenerationService, JwtAuthGuard],