-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
## 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
- Loading branch information
Showing
13 changed files
with
150 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 4 additions & 3 deletions
7
packages/twenty-server/src/engine/core-modules/actor/actor.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
...-server/src/engine/core-modules/actor/query-hooks/created-by.create-one.pre-query-hook.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<FieldMetadataEntity>, | ||
) {} | ||
|
||
async execute( | ||
authContext: AuthContext, | ||
objectName: string, | ||
payload: CreateOneResolverArgs<CustomWorkspaceItem>, | ||
): Promise<CreateOneResolverArgs<CustomWorkspaceItem>> { | ||
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<WorkspaceMemberWorkspaceEntity>( | ||
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; | ||
} | ||
} |