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 377d7d6a6..f6964f796 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 abd5acc6d..bc2a0fb61 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 13f65996e..9543bbdaa 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 dcb529fdd..7e3cfc8ac 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 8f11c354f..5150e1a2f 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 8ed96cf1c..5b73e80de 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 b607e8667..f9d0e5897 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 1f194f18d..a8b730c4a 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 ddcf2ff28..69e86b816 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 d87979418..83b10fa91 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 d69cc69a2..4e7b9006b 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 0ef8bab57..816055226 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 000000000..03ba6e648 --- /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; + } +}