Files
twenty/packages/twenty-server/src/engine/metadata-modules/object-metadata/object-metadata-v2.service.ts
T
Paul Rastoin 83a560c936 Refactor FieldMetadataService and validation to consume FlatObjectMetadataMaps (#13719)
# Introduction
Following recent `FlatObjectMetadataMaps` manipulation, transpilers
utils introduction in https://github.com/twentyhq/twenty/pull/13620
Refactored the field metadata service and validator to iterate over
`FlatObjectMetadataMaps` instead of `FlatObjectMetadata[]`.

The object metadata service v2 is shadow coding
2025-08-07 17:19:07 +02:00

71 lines
3.3 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
import { Repository } from 'typeorm';
import { fromCreateObjectInputToFlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-create-object-input-to-flat-object-metadata.util';
import { WorkspaceMetadataCacheService } from 'src/engine/metadata-modules/workspace-metadata-cache/services/workspace-metadata-cache.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 { FlatObjectMetadataMaps } from 'src/engine/metadata-modules/flat-object-metadata-maps/types/flat-object-metadata-maps.type';
import { fromFlatObjectMetadataMapsToFlatObjectMetadatas } from 'src/engine/metadata-modules/flat-object-metadata/utils/from-flat-object-metadata-maps-to-flat-object-metadatas.util';
import { ObjectMetadataEntity } from './object-metadata.entity';
import { CreateObjectInput } from './dtos/create-object.input';
@Injectable()
export class ObjectMetadataServiceV2 extends TypeOrmQueryService<ObjectMetadataEntity> {
constructor(
@InjectRepository(ObjectMetadataEntity, 'core')
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
private readonly workspaceMetadataCacheService: WorkspaceMetadataCacheService,
private readonly workspaceMigrationBuilderV2: WorkspaceMigrationBuilderV2Service,
private readonly workspaceMigrationRunnerV2Service: WorkspaceMigrationRunnerV2Service,
) {
super(objectMetadataRepository);
}
override async createOne(
objectMetadataInput: CreateObjectInput,
): Promise<ObjectMetadataEntity> {
const { flatObjectMetadataMaps } =
await this.workspaceMetadataCacheService.getExistingOrRecomputeFlatObjectMetadataMaps(
{
workspaceId: objectMetadataInput.workspaceId,
},
);
const createdRawFlatObjectMetadata =
fromCreateObjectInputToFlatObjectMetadata(objectMetadataInput);
const existingFlatObjectMetadatas: FlatObjectMetadataMaps = {
byId: {},
idByNameSingular: {},
};
// @ts-expect-error TODO implement validateFlatObjectMetadata
const createdFlatObjectMetadata = validateFlatObjectMetadata({
existing:
// Here we assume that EVERYTHING is in cache and up to date, this is very critical, also race condition prone :thinking:
fromFlatObjectMetadataMapsToFlatObjectMetadatas(flatObjectMetadataMaps),
toValidate: [createdRawFlatObjectMetadata],
});
const workspaceMigration = this.workspaceMigrationBuilderV2.build({
objectMetadataFromToInputs: {
from: fromFlatObjectMetadataMapsToFlatObjectMetadatas(
existingFlatObjectMetadatas,
),
to: [createdFlatObjectMetadata],
},
inferDeletionFromMissingObjectFieldIndex: false,
workspaceId: objectMetadataInput.workspaceId,
});
await this.workspaceMigrationRunnerV2Service.run(workspaceMigration);
return createdFlatObjectMetadata; // TODO retrieve from cache
}
}