Object metadata API create one using workspace migration v2 (#13420)
# Introduction In this PR we create basic transpilation methods and utils to handle input to flat, entity to flat, object maps to flat. In order to transpile everything into a common validation that will be implemented in another PR ## FieldMetadataEntity typing Added `never | null` to fields that should never be in order to ease general abstracted method to pass null, as anw it's what is in the database ## Todo - ~~Create a feature flag~~ - Integration test for object creation through metadata api + pg col introspection and snapshoting
This commit is contained in:
+50
-1
@@ -13,8 +13,12 @@ import {
|
||||
Repository,
|
||||
} from 'typeorm';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { fromObjectMetadataMapsToFlatObjectMetadatas } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-object-metadata-maps-to-flat-object-metadatas.util';
|
||||
import { mergeTwoFlatFieldObjectMetadatas } from 'src/engine/metadata-modules/flat-object-metadata/utils/merge-two-flat-object-metadatas.util';
|
||||
import { IndexMetadataService } from 'src/engine/metadata-modules/index-metadata/index-metadata.service';
|
||||
import { DeleteOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/delete-object.input';
|
||||
import {
|
||||
@@ -46,12 +50,17 @@ import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target
|
||||
import { isFieldMetadataEntityOfType } from 'src/engine/utils/is-field-metadata-of-type.util';
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
||||
import { WorkspaceMigrationBuilderV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-builder-v2.service';
|
||||
import { WorkspaceMigrationRunnerV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/workspace-migration-runner-v2.service';
|
||||
import { CUSTOM_OBJECT_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
import { isSearchableFieldType } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-searchable-field.util';
|
||||
|
||||
import { ObjectMetadataEntity } from './object-metadata.entity';
|
||||
|
||||
import { CreateObjectInput } from './dtos/create-object.input';
|
||||
import {
|
||||
CreateObjectInput,
|
||||
fromCreateObjectInputToFlatObjectMetadata,
|
||||
} from './dtos/create-object.input';
|
||||
|
||||
@Injectable()
|
||||
export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEntity> {
|
||||
@@ -70,6 +79,9 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
private readonly indexMetadataService: IndexMetadataService,
|
||||
private readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
|
||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||
private readonly workspaceMigrationBuilderV2: WorkspaceMigrationBuilderV2Service,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
private readonly workspaceMigrationRunnerV2Service: WorkspaceMigrationRunnerV2Service,
|
||||
) {
|
||||
super(objectMetadataRepository);
|
||||
}
|
||||
@@ -116,6 +128,43 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
objectMetadataInput.workspaceId,
|
||||
);
|
||||
|
||||
const isWorkspaceMigrationV2Enabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
||||
objectMetadataInput.workspaceId,
|
||||
);
|
||||
|
||||
if (isWorkspaceMigrationV2Enabled) {
|
||||
const createdRawFlatObjectMetadata =
|
||||
fromCreateObjectInputToFlatObjectMetadata(objectMetadataInput);
|
||||
const existingFlatObjectMetadatas =
|
||||
fromObjectMetadataMapsToFlatObjectMetadatas(objectMetadataMaps);
|
||||
// @ts-expect-error TODO implement validateFlatObjectMetadataData
|
||||
const createdFlatObjectMetadata = validateFlatObjectMetadataData({
|
||||
existing:
|
||||
// Here we assume that EVERYTHING is in cache and up to date, this is very critical, also race condition prone :thinking:
|
||||
fromObjectMetadataMapsToFlatObjectMetadatas(objectMetadataMaps),
|
||||
toValidate: [createdRawFlatObjectMetadata],
|
||||
});
|
||||
|
||||
const workpsaceMigration = this.workspaceMigrationBuilderV2.build({
|
||||
objectMetadataFromToInputs: {
|
||||
from: existingFlatObjectMetadatas,
|
||||
to: mergeTwoFlatFieldObjectMetadatas({
|
||||
destFlatObjectMetadatas: existingFlatObjectMetadatas,
|
||||
toMergeFlatObjectMetadatas: [createdFlatObjectMetadata],
|
||||
}),
|
||||
},
|
||||
workspaceId: objectMetadataInput.workspaceId, // Where does this comes from ?
|
||||
});
|
||||
|
||||
await this.workspaceMigrationRunnerV2Service.run(workpsaceMigration);
|
||||
|
||||
// What to return exactly ? We now won't have access to the entity directly
|
||||
// We could still retrieve it afterwards using a find on object metadata id or return a flat now
|
||||
return createdFlatObjectMetadata;
|
||||
}
|
||||
|
||||
objectMetadataInput.labelSingular = capitalize(
|
||||
objectMetadataInput.labelSingular,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user