feat: Dynamic hook registration for WorkspaceQueryHooks (#6008)

#### Overview

This PR introduces a new API for dynamically registering and executing
pre and post query hooks in the Workspace Query Hook system using the
`@WorkspaceQueryHook` decorator. This approach eliminates the need for
manual provider registration, and fix the issue of `undefined` or `null`
repository using `@InjectWorkspaceRepository`.

#### New API

**Define a Hook**

Use the `@WorkspaceQueryHook` decorator to define pre or post hooks:

```typescript
@WorkspaceQueryHook({
  key: `calendarEvent.findMany`,
  scope: Scope.REQUEST,
})
export class CalendarEventFindManyPreQueryHook implements WorkspaceQueryHookInstance {
  async execute(userId: string, workspaceId: string, payload: FindManyResolverArgs): Promise<void> {
    if (!payload?.filter?.id?.eq) {
      throw new BadRequestException('id filter is required');
    }

    // Implement hook logic here
  }
}
```

This API simplifies the registration and execution of query hooks,
providing a more flexible and maintainable approach.

---------

Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
Jérémy M
2024-06-25 12:41:46 +02:00
committed by GitHub
parent 4dfca45fd3
commit 7c2e745b45
32 changed files with 472 additions and 235 deletions

View File

@ -1,15 +1,16 @@
import { Injectable } from '@nestjs/common';
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
import { CreateManyResolverArgs } 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 {
BlocklistItem,
BlocklistValidationService,
} from 'src/modules/connected-account/services/blocklist/blocklist-validation.service';
@Injectable()
export class BlocklistCreateManyPreQueryHook implements WorkspacePreQueryHook {
@WorkspaceQueryHook(`blocklist.createMany`)
export class BlocklistCreateManyPreQueryHook
implements WorkspaceQueryHookInstance
{
constructor(
private readonly blocklistValidationService: BlocklistValidationService,
) {}

View File

@ -1,9 +1,13 @@
import { Injectable, MethodNotAllowedException } from '@nestjs/common';
import { MethodNotAllowedException } from '@nestjs/common';
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
@Injectable()
export class BlocklistUpdateManyPreQueryHook implements WorkspacePreQueryHook {
import { WorkspaceQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/decorators/workspace-query-hook.decorator';
@WorkspaceQueryHook(`blocklist.updateMany`)
export class BlocklistUpdateManyPreQueryHook
implements WorkspaceQueryHookInstance
{
constructor() {}
async execute(): Promise<void> {

View File

@ -1,15 +1,16 @@
import { Injectable } from '@nestjs/common';
import { WorkspacePreQueryHook } from 'src/engine/api/graphql/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
import { WorkspaceQueryHookInstance } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/interfaces/workspace-query-hook.interface';
import { UpdateOneResolverArgs } 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 {
BlocklistItem,
BlocklistValidationService,
} from 'src/modules/connected-account/services/blocklist/blocklist-validation.service';
@Injectable()
export class BlocklistUpdateOnePreQueryHook implements WorkspacePreQueryHook {
@WorkspaceQueryHook(`blocklist.updateOne`)
export class BlocklistUpdateOnePreQueryHook
implements WorkspaceQueryHookInstance
{
constructor(
private readonly blocklistValidationService: BlocklistValidationService,
) {}

View File

@ -8,18 +8,9 @@ import { BlocklistValidationModule } from 'src/modules/connected-account/service
@Module({
imports: [BlocklistValidationModule],
providers: [
{
provide: BlocklistCreateManyPreQueryHook.name,
useClass: BlocklistCreateManyPreQueryHook,
},
{
provide: BlocklistUpdateManyPreQueryHook.name,
useClass: BlocklistUpdateManyPreQueryHook,
},
{
provide: BlocklistUpdateOnePreQueryHook.name,
useClass: BlocklistUpdateOnePreQueryHook,
},
BlocklistCreateManyPreQueryHook,
BlocklistUpdateManyPreQueryHook,
BlocklistUpdateOnePreQueryHook,
],
})
export class ConnectedAccountQueryHookModule {}