From 04c359a5dcd3d16df196fe903b742e01ed7fe674 Mon Sep 17 00:00:00 2001 From: Weiko Date: Thu, 21 Nov 2024 22:53:22 +0100 Subject: [PATCH] Fix record creation (#8664) ## Context Now that each operation has its own resolver, we need to make sure they all map to query arg getters. CreateOne was not properly mapped to the position getter which made record creation fail because "position: first" was not properly converted to a float. Also fixing queries with custom object where we were wrongly using the table name instead of entity name --- ...phql-query-delete-many-resolver.service.ts | 8 +- ...hql-query-destroy-many-resolver.service.ts | 8 +- ...-query-find-duplicates-resolver.service.ts | 8 +- ...raphql-query-find-many-resolver.service.ts | 12 +- ...graphql-query-find-one-resolver.service.ts | 8 +- ...hql-query-restore-many-resolver.service.ts | 8 +- .../graphql-query-search-resolver.service.ts | 8 +- ...phql-query-update-many-resolver.service.ts | 8 +- .../factories/query-runner-args.factory.ts | 14 +++ .../workspace-query-hook.decorator.ts | 2 +- .../engine/core-modules/actor/actor.module.ts | 7 +- ... created-by.create-many.pre-query-hook.ts} | 6 +- .../created-by.create-one.pre-query-hook.ts | 117 ++++++++++++++++++ 13 files changed, 150 insertions(+), 64 deletions(-) rename packages/twenty-server/src/engine/core-modules/actor/query-hooks/{created-by.pre-query-hook.ts => created-by.create-many.pre-query-hook.ts} (96%) create mode 100644 packages/twenty-server/src/engine/core-modules/actor/query-hooks/created-by.create-one.pre-query-hook.ts diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-many-resolver.service.ts index 377d7d6a61..f6964f796c 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-delete-many-resolver.service.ts @@ -14,7 +14,6 @@ import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-que import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; @Injectable() export class GraphqlQueryDeleteManyResolverService extends GraphqlQueryBaseResolverService< @@ -31,14 +30,9 @@ export class GraphqlQueryDeleteManyResolverService extends GraphqlQueryBaseResol objectMetadataItemWithFieldMaps.nameSingular, ); - const tableName = computeTableName( - objectMetadataItemWithFieldMaps.nameSingular, - objectMetadataItemWithFieldMaps.isCustom, - ); - executionArgs.graphqlQueryParser.applyFilterToBuilder( queryBuilder, - tableName, + objectMetadataItemWithFieldMaps.nameSingular, executionArgs.args.filter, ); diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-many-resolver.service.ts index abd5acc6de..bc2a0fb613 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-destroy-many-resolver.service.ts @@ -12,7 +12,6 @@ import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/c import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper'; import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; @Injectable() export class GraphqlQueryDestroyManyResolverService extends GraphqlQueryBaseResolverService< @@ -29,14 +28,9 @@ export class GraphqlQueryDestroyManyResolverService extends GraphqlQueryBaseReso objectMetadataItemWithFieldMaps.nameSingular, ); - const tableName = computeTableName( - objectMetadataItemWithFieldMaps.nameSingular, - objectMetadataItemWithFieldMaps.isCustom, - ); - executionArgs.graphqlQueryParser.applyFilterToBuilder( queryBuilder, - tableName, + objectMetadataItemWithFieldMaps.nameSingular, executionArgs.args.filter, ); diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-duplicates-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-duplicates-resolver.service.ts index 13f65996eb..9543bbdaa1 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-duplicates-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-duplicates-resolver.service.ts @@ -28,7 +28,6 @@ import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/typ import { getObjectMetadataMapItemByNameSingular } from 'src/engine/metadata-modules/utils/get-object-metadata-map-item-by-name-singular.util'; import { formatData } from 'src/engine/twenty-orm/utils/format-data.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; @Injectable() export class GraphqlQueryFindDuplicatesResolverService extends GraphqlQueryBaseResolverService< @@ -111,14 +110,9 @@ export class GraphqlQueryFindDuplicatesResolverService extends GraphqlQueryBaseR objectMetadataItemWithFieldMaps.nameSingular, ); - const tableName = computeTableName( - objectMetadataItemWithFieldMaps.nameSingular, - objectMetadataItemWithFieldMaps.isCustom, - ); - graphqlQueryParser.applyFilterToBuilder( duplicateRecordsQueryBuilder, - tableName, + objectMetadataItemWithFieldMaps.nameSingular, duplicateConditions, ); diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts index dcb529fdd2..7e3cfc8acf 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-many-resolver.service.ts @@ -30,7 +30,6 @@ import { 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 { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; import { isDefined } from 'src/utils/is-defined'; @Injectable() @@ -57,14 +56,9 @@ export class GraphqlQueryFindManyResolverService extends GraphqlQueryBaseResolve let appliedFilters = executionArgs.args.filter ?? ({} as ObjectRecordFilter); - const tableName = computeTableName( - objectMetadataItemWithFieldMaps.nameSingular, - objectMetadataItemWithFieldMaps.isCustom, - ); - executionArgs.graphqlQueryParser.applyFilterToBuilder( aggregateQueryBuilder, - tableName, + objectMetadataItemWithFieldMaps.nameSingular, appliedFilters, ); @@ -99,14 +93,14 @@ export class GraphqlQueryFindManyResolverService extends GraphqlQueryBaseResolve executionArgs.graphqlQueryParser.applyFilterToBuilder( queryBuilder, - tableName, + objectMetadataItemWithFieldMaps.nameSingular, appliedFilters, ); executionArgs.graphqlQueryParser.applyOrderToBuilder( queryBuilder, orderByWithIdCondition, - tableName, + objectMetadataItemWithFieldMaps.nameSingular, isForwardPagination, ); diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service.ts index 8f11c354fe..5150e1a2f1 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-find-one-resolver.service.ts @@ -23,7 +23,6 @@ import { WorkspaceQueryRunnerExceptionCode, } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.exception'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; @Injectable() export class GraphqlQueryFindOneResolverService extends GraphqlQueryBaseResolverService< @@ -40,14 +39,9 @@ export class GraphqlQueryFindOneResolverService extends GraphqlQueryBaseResolver objectMetadataItemWithFieldMaps.nameSingular, ); - const tableName = computeTableName( - objectMetadataItemWithFieldMaps.nameSingular, - objectMetadataItemWithFieldMaps.isCustom, - ); - executionArgs.graphqlQueryParser.applyFilterToBuilder( queryBuilder, - tableName, + objectMetadataItemWithFieldMaps.nameSingular, executionArgs.args.filter ?? ({} as ObjectRecordFilter), ); diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service.ts index 8ed96cf1ca..5b73e80def 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-restore-many-resolver.service.ts @@ -14,7 +14,6 @@ import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-que import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner/utils/assert-is-valid-uuid.util'; import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; @Injectable() export class GraphqlQueryRestoreManyResolverService extends GraphqlQueryBaseResolverService< @@ -31,14 +30,9 @@ export class GraphqlQueryRestoreManyResolverService extends GraphqlQueryBaseReso objectMetadataItemWithFieldMaps.nameSingular, ); - const tableName = computeTableName( - objectMetadataItemWithFieldMaps.nameSingular, - objectMetadataItemWithFieldMaps.isCustom, - ); - executionArgs.graphqlQueryParser.applyFilterToBuilder( queryBuilder, - tableName, + objectMetadataItemWithFieldMaps.nameSingular, executionArgs.args.filter, ); diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts index b607e86672..f9d0e58971 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-search-resolver.service.ts @@ -20,7 +20,6 @@ import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/g import { ProcessNestedRelationsHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/process-nested-relations.helper'; import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/constants/search-vector-field.constants'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; import { isDefined } from 'src/utils/is-defined'; @Injectable() @@ -64,14 +63,9 @@ export class GraphqlQuerySearchResolverService extends GraphqlQueryBaseResolverS objectMetadataItemWithFieldMaps.nameSingular, ); - const tableName = computeTableName( - objectMetadataItemWithFieldMaps.nameSingular, - objectMetadataItemWithFieldMaps.isCustom, - ); - executionArgs.graphqlQueryParser.applyFilterToBuilder( queryBuilder, - tableName, + objectMetadataItemWithFieldMaps.nameSingular, executionArgs.args.filter ?? ({} as ObjectRecordFilter), ); diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service.ts index 1f194f18db..a8b730c4a8 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/resolvers/graphql-query-update-many-resolver.service.ts @@ -15,7 +15,6 @@ import { assertIsValidUuid } from 'src/engine/api/graphql/workspace-query-runner import { assertMutationNotOnRemoteObject } from 'src/engine/metadata-modules/object-metadata/utils/assert-mutation-not-on-remote-object.util'; import { formatData } from 'src/engine/twenty-orm/utils/format-data.util'; import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util'; -import { computeTableName } from 'src/engine/utils/compute-table-name.util'; @Injectable() export class GraphqlQueryUpdateManyResolverService extends GraphqlQueryBaseResolverService< @@ -32,14 +31,9 @@ export class GraphqlQueryUpdateManyResolverService extends GraphqlQueryBaseResol objectMetadataItemWithFieldMaps.nameSingular, ); - const tableName = computeTableName( - objectMetadataItemWithFieldMaps.nameSingular, - objectMetadataItemWithFieldMaps.isCustom, - ); - executionArgs.graphqlQueryParser.applyFilterToBuilder( queryBuilder, - tableName, + objectMetadataItemWithFieldMaps.nameSingular, executionArgs.args.filter, ); diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts index ddcf2ff282..69e86b8164 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/factories/query-runner-args.factory.ts @@ -7,6 +7,7 @@ import { import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface'; import { CreateManyResolverArgs, + CreateOneResolverArgs, FindDuplicatesResolverArgs, FindManyResolverArgs, FindOneResolverArgs, @@ -43,6 +44,19 @@ export class QueryRunnerArgsFactory { ); switch (resolverArgsType) { + case ResolverArgsType.CreateOne: + return { + ...args, + data: await this.overrideDataByFieldMetadata( + (args as CreateOneResolverArgs).data, + options, + fieldMetadataMapByNameByName, + { + argIndex: 0, + shouldBackfillPosition, + }, + ), + } satisfies CreateOneResolverArgs; case ResolverArgsType.CreateMany: return { ...args, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator.ts index d879794186..83b10fa918 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator.ts @@ -3,8 +3,8 @@ import { SCOPE_OPTIONS_METADATA } from '@nestjs/common/constants'; import { WorkspaceResolverBuilderMethodNames } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; -import { WORKSPACE_QUERY_HOOK_METADATA } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.constants'; import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type'; +import { WORKSPACE_QUERY_HOOK_METADATA } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.constants'; export type WorkspaceQueryHookKey = `${string}.${WorkspaceResolverBuilderMethodNames}`; diff --git a/packages/twenty-server/src/engine/core-modules/actor/actor.module.ts b/packages/twenty-server/src/engine/core-modules/actor/actor.module.ts index d69cc69a23..4e7b9006bb 100644 --- a/packages/twenty-server/src/engine/core-modules/actor/actor.module.ts +++ b/packages/twenty-server/src/engine/core-modules/actor/actor.module.ts @@ -1,12 +1,13 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { CreatedByPreQueryHook } from 'src/engine/core-modules/actor/query-hooks/created-by.pre-query-hook'; +import { CreatedByCreateManyPreQueryHook } from 'src/engine/core-modules/actor/query-hooks/created-by.create-many.pre-query-hook'; +import { CreatedByCreateOnePreQueryHook } from 'src/engine/core-modules/actor/query-hooks/created-by.create-one.pre-query-hook'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; @Module({ imports: [TypeOrmModule.forFeature([FieldMetadataEntity], 'metadata')], - providers: [CreatedByPreQueryHook], - exports: [CreatedByPreQueryHook], + providers: [CreatedByCreateManyPreQueryHook, CreatedByCreateOnePreQueryHook], + exports: [CreatedByCreateManyPreQueryHook, CreatedByCreateOnePreQueryHook], }) export class ActorModule {} diff --git a/packages/twenty-server/src/engine/core-modules/actor/query-hooks/created-by.pre-query-hook.ts b/packages/twenty-server/src/engine/core-modules/actor/query-hooks/created-by.create-many.pre-query-hook.ts similarity index 96% rename from packages/twenty-server/src/engine/core-modules/actor/query-hooks/created-by.pre-query-hook.ts rename to packages/twenty-server/src/engine/core-modules/actor/query-hooks/created-by.create-many.pre-query-hook.ts index 0ef8bab573..8160552261 100644 --- a/packages/twenty-server/src/engine/core-modules/actor/query-hooks/created-by.pre-query-hook.ts +++ b/packages/twenty-server/src/engine/core-modules/actor/query-hooks/created-by.create-many.pre-query-hook.ts @@ -27,8 +27,10 @@ type CustomWorkspaceItem = Omit< }; @WorkspaceQueryHook(`*.createMany`) -export class CreatedByPreQueryHook implements WorkspaceQueryHookInstance { - private readonly logger = new Logger(CreatedByPreQueryHook.name); +export class CreatedByCreateManyPreQueryHook + implements WorkspaceQueryHookInstance +{ + private readonly logger = new Logger(CreatedByCreateManyPreQueryHook.name); constructor( private readonly twentyORMGlobalManager: TwentyORMGlobalManager, diff --git a/packages/twenty-server/src/engine/core-modules/actor/query-hooks/created-by.create-one.pre-query-hook.ts b/packages/twenty-server/src/engine/core-modules/actor/query-hooks/created-by.create-one.pre-query-hook.ts new file mode 100644 index 0000000000..03ba6e648d --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/actor/query-hooks/created-by.create-one.pre-query-hook.ts @@ -0,0 +1,117 @@ +import { Logger } from '@nestjs/common/services/logger.service'; +import { InjectRepository } from '@nestjs/typeorm'; + +import { Repository } from 'typeorm'; + +import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface'; +import { CreateOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface'; + +import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator'; +import { buildCreatedByFromWorkspaceMember } from 'src/engine/core-modules/actor/utils/build-created-by-from-workspace-member.util'; +import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type'; +import { + ActorMetadata, + FieldActorSource, +} from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity'; +import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; +import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity'; + +type CustomWorkspaceItem = Omit< + CustomWorkspaceEntity, + 'createdAt' | 'updatedAt' +> & { + createdAt: string; + updatedAt: string; +}; + +@WorkspaceQueryHook(`*.createOne`) +export class CreatedByCreateOnePreQueryHook + implements WorkspaceQueryHookInstance +{ + private readonly logger = new Logger(CreatedByCreateOnePreQueryHook.name); + + constructor( + private readonly twentyORMGlobalManager: TwentyORMGlobalManager, + @InjectRepository(FieldMetadataEntity, 'metadata') + private readonly fieldMetadataRepository: Repository, + ) {} + + async execute( + authContext: AuthContext, + objectName: string, + payload: CreateOneResolverArgs, + ): Promise> { + let createdBy: ActorMetadata | null = null; + + // TODO: Once all objects have it, we can remove this check + const createdByFieldMetadata = await this.fieldMetadataRepository.findOne({ + where: { + object: { + nameSingular: objectName, + }, + name: 'createdBy', + workspaceId: authContext.workspace.id, + }, + }); + + if (!createdByFieldMetadata) { + return payload; + } + + // If user is logged in, we use the workspace member + if (authContext.workspaceMemberId && authContext.user) { + createdBy = buildCreatedByFromWorkspaceMember( + authContext.workspaceMemberId, + authContext.user, + ); + // TODO: remove that code once we have the workspace member id in all tokens + } else if (authContext.user) { + this.logger.warn("User doesn't have a workspace member id in the token"); + const workspaceMemberRepository = + await this.twentyORMGlobalManager.getRepositoryForWorkspace( + authContext.workspace.id, + 'workspaceMember', + ); + + const workspaceMember = await workspaceMemberRepository.findOne({ + where: { + userId: authContext.user?.id, + }, + }); + + if (!workspaceMember) { + throw new Error( + `Workspace member can't be found for user ${authContext.user.id}`, + ); + } + + createdBy = { + source: FieldActorSource.MANUAL, + workspaceMemberId: workspaceMember.id, + name: `${workspaceMember.name.firstName} ${workspaceMember.name.lastName}`, + }; + } + + if (authContext.apiKey) { + createdBy = { + source: FieldActorSource.API, + name: authContext.apiKey.name, + }; + } + + // Front-end can fill the source field + if ( + createdBy && + (!payload.data.createdBy || !payload.data.createdBy?.name) + ) { + payload.data.createdBy = { + ...createdBy, + source: payload.data.createdBy?.source ?? createdBy.source, + }; + } + + return payload; + } +}