Add activityTarget relation after custom object creation (#2670)

* Add activityTarget relation after custom object creation

* add isCustom check for relations
This commit is contained in:
Weiko 2023-11-23 16:26:33 +01:00 committed by GitHub
parent 4b42ed42dc
commit c795db33b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 126 additions and 3 deletions

View File

@ -56,6 +56,10 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
throw new ConflictException('Field already exists');
}
if (record.name == record.label) {
throw new ConflictException('Field name and label cannot be the same');
}
const createdFieldMetadata = await super.createOne({
...record,
targetColumnMap: generateTargetColumnMap(record.type, true, record.name),

View File

@ -13,6 +13,7 @@ import { WorkspaceMigrationModule } from 'src/metadata/workspace-migration/works
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
import { FieldMetadataEntity } from 'src/metadata/field-metadata/field-metadata.entity';
import { RelationMetadataEntity } from 'src/metadata/relation-metadata/relation-metadata.entity';
import { ObjectMetadataService } from './object-metadata.service';
import { ObjectMetadataEntity } from './object-metadata.entity';
@ -27,7 +28,7 @@ import { ObjectMetadataDTO } from './dtos/object-metadata.dto';
imports: [
TypeORMModule,
NestjsQueryTypeOrmModule.forFeature(
[ObjectMetadataEntity, FieldMetadataEntity],
[ObjectMetadataEntity, FieldMetadataEntity, RelationMetadataEntity],
'metadata',
),
DataSourceModule,

View File

@ -11,9 +11,16 @@ import {
WorkspaceMigrationColumnCreate,
WorkspaceMigrationTableAction,
} from 'src/metadata/workspace-migration/workspace-migration.entity';
import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity';
import {
FieldMetadataEntity,
FieldMetadataType,
} from 'src/metadata/field-metadata/field-metadata.entity';
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
import {
RelationMetadataEntity,
RelationMetadataType,
} from 'src/metadata/relation-metadata/relation-metadata.entity';
import { ObjectMetadataEntity } from './object-metadata.entity';
@ -25,6 +32,12 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
@InjectRepository(ObjectMetadataEntity, 'metadata')
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
@InjectRepository(FieldMetadataEntity, 'metadata')
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
@InjectRepository(RelationMetadataEntity, 'metadata')
private readonly relationMetadataRepository: Repository<RelationMetadataEntity>,
private readonly dataSourceService: DataSourceService,
private readonly typeORMService: TypeORMService,
private readonly workspaceMigrationService: WorkspaceMigrationService,
@ -117,6 +130,86 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
],
});
const activityTargetObjectMetadata =
await this.objectMetadataRepository.findOneByOrFail({
nameSingular: 'activityTarget',
workspaceId: record.workspaceId,
});
const activityTargetRelationFieldMetadata =
await this.fieldMetadataRepository.save([
// FROM
{
objectMetadataId: createdObjectMetadata.id,
workspaceId: record.workspaceId,
isCustom: true,
isActive: true,
type: FieldMetadataType.RELATION,
name: 'activityTargets',
label: 'Activities',
targetColumnMap: {},
description: `Activities tied to the ${record.labelSingular}`,
icon: 'IconCheckbox',
isNullable: true,
},
// TO
{
objectMetadataId: activityTargetObjectMetadata.id,
workspaceId: record.workspaceId,
isCustom: true,
isActive: true,
type: FieldMetadataType.RELATION,
name: record.nameSingular,
label: record.labelSingular,
targetColumnMap: {},
description: `ActivityTarget ${record.labelSingular}`,
icon: 'IconBuildingSkyscraper',
isNullable: true,
},
// Foreign key
{
objectMetadataId: activityTargetObjectMetadata.id,
workspaceId: record.workspaceId,
isCustom: true,
isActive: true,
type: FieldMetadataType.UUID,
name: `${createdObjectMetadata.targetTableName}Id`,
label: `${record.labelSingular} ID (foreign key)`,
targetColumnMap: {},
description: `ActivityTarget ${record.labelSingular} id foreign key`,
icon: undefined,
isNullable: true,
isSystem: true,
defaultValue: undefined,
},
]);
const activityTargetRelationFieldMetadataMap =
activityTargetRelationFieldMetadata.reduce(
(acc, fieldMetadata: FieldMetadataEntity) => {
if (fieldMetadata.type === FieldMetadataType.RELATION) {
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
}
return acc;
},
{},
);
await this.relationMetadataRepository.save([
{
workspaceId: record.workspaceId,
relationType: RelationMetadataType.ONE_TO_MANY,
fromObjectMetadataId: createdObjectMetadata.id,
toObjectMetadataId: activityTargetObjectMetadata.id,
fromFieldMetadataId:
activityTargetRelationFieldMetadataMap[createdObjectMetadata.id].id,
toFieldMetadataId:
activityTargetRelationFieldMetadataMap[
activityTargetObjectMetadata.id
].id,
},
]);
await this.workspaceMigrationService.createCustomMigration(
createdObjectMetadata.workspaceId,
[
@ -124,6 +217,30 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
name: createdObjectMetadata.targetTableName,
action: 'create',
} satisfies WorkspaceMigrationTableAction,
// Add activity target relation
{
name: activityTargetObjectMetadata.targetTableName,
action: 'alter',
columns: [
{
action: WorkspaceMigrationColumnActionType.CREATE,
columnName: `${createdObjectMetadata.targetTableName}Id`,
columnType: 'uuid',
} satisfies WorkspaceMigrationColumnCreate,
],
},
{
name: activityTargetObjectMetadata.targetTableName,
action: 'alter',
columns: [
{
action: WorkspaceMigrationColumnActionType.RELATION,
columnName: `${createdObjectMetadata.targetTableName}Id`,
referencedTableName: createdObjectMetadata.targetTableName,
referencedTableColumnName: 'id',
},
],
},
// This is temporary until we implement mainIdentifier
{
name: createdObjectMetadata.targetTableName,

View File

@ -95,7 +95,7 @@ export class CompositeFieldAliasFactory {
}
`;
}
let relationAlias = fieldKey;
let relationAlias = fieldMetadata.isCustom ? `_${fieldKey}` : fieldKey;
// For one to one relations, pg_graphql use the targetTableName on the side that is not storing the foreign key
// so we need to alias it to the field key

View File

@ -18,4 +18,5 @@ export interface FieldMetadataInterface<
isNullable?: boolean;
fromRelationMetadata?: RelationMetadataEntity;
toRelationMetadata?: RelationMetadataEntity;
isCustom?: boolean;
}