From 0b60aa4249de38bf5f72157cfcc5ea7b4861c2d7 Mon Sep 17 00:00:00 2001 From: Weiko Date: Fri, 3 Oct 2025 00:20:21 +0200 Subject: [PATCH] Add custom routes to migration v2 (#14846) ## Context Add routes to migration V2 - Resolvers - Service v2 - Builder - Validator - Action runner Next PR: Add to twenty-cli to sync routes with serverless --- .../src/generated-metadata/graphql.ts | 90 ++++++- .../twenty-front/src/generated/graphql.ts | 41 +++- .../hooks/useUpdateOneServerlessFunction.ts | 10 +- .../WorkflowEditActionServerlessFunction.tsx | 2 +- ...rverlessFunctionIdInTriggersNonNullable.ts | 67 +++++ ...1759418198310-renameRouteToRouteTrigger.ts | 55 +++++ .../application/application-sync.service.ts | 20 +- ...ll-flat-entity-maps-properties.constant.ts | 1 + .../empty-all-flat-entity-maps.constant.ts | 1 + ...t-entities-by-metadata-engine-name.type.ts | 2 + .../dtos/update-cron-trigger.input.ts | 27 ++- .../entities/cron-trigger.entity.ts | 4 +- .../exceptions/cron-trigger.exception.ts | 1 + .../services/cron-trigger-v2.service.ts | 24 +- ...at-cron-trigger-to-update-or-throw.util.ts | 2 +- .../update-database-event-trigger.input.ts | 27 ++- .../entities/database-event-trigger.entity.ts | 4 +- .../database-event-trigger.exception.ts | 2 + .../database-event-trigger-v2.service.ts | 27 ++- ...e-event-trigger-to-update-or-throw.util.ts | 2 +- ...n-field-input-transpilations-error.util.ts | 1 + .../metadata-engine.module.ts | 4 +- ...te-trigger-editable-properties.constant.ts | 7 + ...-trigger-properties-to-compare.constant.ts | 6 + .../dtos/create-route-trigger.input.ts | 37 +++ .../dtos/route-trigger-id.input.ts | 11 + .../route-trigger/dtos/route-trigger.dto.ts | 32 +++ .../dtos/update-route-trigger.input.ts | 48 ++++ .../exceptions/route-trigger.exception.ts | 16 ++ .../resolvers/route-trigger.resolver.ts | 99 ++++++++ .../route-trigger.controller.ts} | 20 +- .../route-trigger.entity.ts} | 21 +- .../route-trigger/route-trigger.module.ts | 34 +++ .../route-trigger.service.ts} | 51 ++-- .../services/route-trigger-v2.service.ts | 228 ++++++++++++++++++ ...ce-flat-route-trigger-map-cache.service.ts | 69 ++++++ ...oute-trigger-properties-to-compare.type.ts | 4 + .../types/flat-route-trigger.type.ts | 17 ++ .../compare-two-flat-route-trigger.util.ts | 59 +++++ ...rigger-input-to-flat-route-trigger.util.ts | 27 +++ ...t-route-trigger-to-update-or-throw.util.ts | 33 +++ ...ger-graphql-api-exception-handler.utils.ts | 23 ++ .../metadata-modules/route/route.module.ts | 21 -- .../dtos/update-serverless-function.input.ts | 28 ++- .../serverless-function.entity.ts | 16 +- .../serverless-function.service.ts | 8 +- .../types/flat-serverless-function.type.ts | 4 +- ...erless-function-to-update-or-throw.util.ts | 6 +- ...ty-orchestrator-actions-report.constant.ts | 1 + ...ption-to-validation-response-error.util.ts | 2 + ...ce-migration-build-orchestrator.service.ts | 50 +++- ...n-trigger-related-flat-entity-maps.type.ts | 6 + ...-v2-cron-trigger-action-builder.service.ts | 30 ++- ...t-trigger-related-flat-entity-maps.type.ts | 6 + ...e-event-trigger-actions-builder.service.ts | 30 ++- ...e-trigger-related-flat-entity-maps.type.ts | 6 + ...2-route-trigger-actions-builder.service.ts | 159 ++++++++++++ ...iew-field-related-flat-entity-maps.type.ts | 0 ...n-v2-view-field-actions-builder.service.ts | 2 +- .../workspace-migration-action-common-v2.ts | 4 +- ...-migration-route-trigger-action-v2.type.ts | 31 +++ .../flat-cron-trigger-validator.service.ts | 30 +++ ...atabase-event-trigger-validator.service.ts | 30 +++ .../flat-route-trigger-validator.service.ts | 147 +++++++++++ .../flat-view-field-validator.service.ts | 2 +- ...ace-migration-builder-validators.module.ts | 7 +- .../workspace-migration-builder-v2.module.ts | 4 + ...te-route-trigger-action-handler.service.ts | 31 +++ ...te-route-trigger-action-handler.service.ts | 31 +++ ...te-route-trigger-action-handler.service.ts | 32 +++ ...migration-runner-action-handlers.module.ts | 7 + ...ate-view-field-v2.integration-spec.ts.snap | 4 + ...ne-field-metadata.integration-spec.ts.snap | 2 + ...ne-field-metadata.integration-spec.ts.snap | 4 + ...-metadata-enum-v2.integration-spec.ts.snap | 140 +++++++++++ ...field-metadata-v2.integration-spec.ts.snap | 136 +++++++++++ ...morph-relation-v2.integration-spec.ts.snap | 34 +++ ...relation-creation.integration-spec.ts.snap | 40 +++ ...a-relation-update.integration-spec.ts.snap | 4 + ...bject-metadata-v2.integration-spec.ts.snap | 42 ++++ 80 files changed, 2242 insertions(+), 151 deletions(-) create mode 100644 packages/twenty-server/src/database/typeorm/core/migrations/common/1759417994272-setServerlessFunctionIdInTriggersNonNullable.ts create mode 100644 packages/twenty-server/src/database/typeorm/core/migrations/common/1759418198310-renameRouteToRouteTrigger.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-editable-properties.constant.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-properties-to-compare.constant.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts rename packages/twenty-server/src/engine/metadata-modules/{route/route.controller.ts => route-trigger/route-trigger.controller.ts} (63%) rename packages/twenty-server/src/engine/metadata-modules/{route/route.entity.ts => route-trigger/route-trigger.entity.ts} (66%) create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.module.ts rename packages/twenty-server/src/engine/metadata-modules/{route/route.service.ts => route-trigger/route-trigger.service.ts} (68%) create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger-properties-to-compare.type.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/compare-two-flat-route-trigger.util.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-create-route-trigger-input-to-flat-route-trigger.util.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-update-route-trigger-input-to-flat-route-trigger-to-update-or-throw.util.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/route-trigger-graphql-api-exception-handler.utils.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route/route.module.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/types/cron-trigger-related-flat-entity-maps.type.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/types/database-event-trigger-related-flat-entity-maps.type.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/types/route-trigger-related-flat-entity-maps.type.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service.ts rename packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/{ => view-field}/types/view-field-related-flat-entity-maps.type.ts (100%) create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/create-route-trigger-action-handler.service.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service.ts create mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/update-route-trigger-action-handler.service.ts diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 01010186ead..e5b405fb60a 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -836,6 +836,13 @@ export type CreateRoleInput = { label: Scalars['String']; }; +export type CreateRouteTriggerInput = { + httpMethod?: HttpMethod; + isAuthRequired?: Scalars['Boolean']; + path: Scalars['String']; + serverlessFunctionId: Scalars['String']; +}; + export type CreateServerlessFunctionInput = { code?: InputMaybe; description?: InputMaybe; @@ -1406,6 +1413,14 @@ export type GridPositionInput = { rowSpan: Scalars['Float']; }; +export enum HttpMethod { + DELETE = 'DELETE', + GET = 'GET', + PATCH = 'PATCH', + POST = 'POST', + PUT = 'PUT' +} + export enum HealthIndicatorId { app = 'app', connectedAccount = 'connectedAccount', @@ -1644,6 +1659,7 @@ export type Mutation = { createOneObject: Object; createOneRemoteServer: RemoteServer; createOneRole: Role; + createOneRouteTrigger: RouteTrigger; createOneServerlessFunction: ServerlessFunction; createOneServerlessFunctionLayer: ServerlessFunctionLayer; createPageLayout: PageLayout; @@ -1673,6 +1689,7 @@ export type Mutation = { deleteOneObject: Object; deleteOneRemoteServer: RemoteServer; deleteOneRole: Scalars['String']; + deleteOneRouteTrigger: RouteTrigger; deleteOneServerlessFunction: ServerlessFunction; deletePageLayout: PageLayout; deletePageLayoutTab: Scalars['Boolean']; @@ -1756,6 +1773,7 @@ export type Mutation = { updateOneObject: Object; updateOneRemoteServer: RemoteServer; updateOneRole: Role; + updateOneRouteTrigger: RouteTrigger; updateOneServerlessFunction: ServerlessFunction; updatePageLayout: PageLayout; updatePageLayoutTab: PageLayoutTab; @@ -1955,6 +1973,11 @@ export type MutationCreateOneRoleArgs = { }; +export type MutationCreateOneRouteTriggerArgs = { + input: CreateRouteTriggerInput; +}; + + export type MutationCreateOneServerlessFunctionArgs = { input: CreateServerlessFunctionInput; }; @@ -2096,6 +2119,11 @@ export type MutationDeleteOneRoleArgs = { }; +export type MutationDeleteOneRouteTriggerArgs = { + input: RouteTriggerIdInput; +}; + + export type MutationDeleteOneServerlessFunctionArgs = { input: ServerlessFunctionIdInput; }; @@ -2504,6 +2532,11 @@ export type MutationUpdateOneRoleArgs = { }; +export type MutationUpdateOneRouteTriggerArgs = { + input: UpdateRouteTriggerInput; +}; + + export type MutationUpdateOneServerlessFunctionArgs = { input: UpdateServerlessFunctionInput; }; @@ -2969,11 +3002,13 @@ export type Query = { findManyDatabaseEventTriggers: Array; findManyPublicDomains: Array; findManyRemoteServersByType: Array; + findManyRouteTriggers: Array; findManyServerlessFunctions: Array; findOneAgent: Agent; findOneCronTrigger: CronTrigger; findOneDatabaseEventTrigger: DatabaseEventTrigger; findOneRemoteServerById: RemoteServer; + findOneRouteTrigger: RouteTrigger; findOneServerlessFunction: ServerlessFunction; findWorkspaceFromInviteHash: Workspace; findWorkspaceInvitations: Array; @@ -3118,6 +3153,11 @@ export type QueryFindOneRemoteServerByIdArgs = { }; +export type QueryFindOneRouteTriggerArgs = { + input: RouteTriggerIdInput; +}; + + export type QueryFindOneServerlessFunctionArgs = { input: ServerlessFunctionIdInput; }; @@ -3476,6 +3516,22 @@ export type Role = { workspaceMembers: Array; }; +export type RouteTrigger = { + __typename?: 'RouteTrigger'; + createdAt: Scalars['DateTime']; + httpMethod: HttpMethod; + id: Scalars['ID']; + isAuthRequired: Scalars['Boolean']; + path: Scalars['String']; + serverlessFunctionId: Scalars['String']; + updatedAt: Scalars['DateTime']; + workspaceId: Scalars['String']; +}; + +export type RouteTriggerIdInput = { + id: Scalars['String']; +}; + export type RunWorkflowVersionInput = { /** Execution result in JSON format */ payload?: InputMaybe; @@ -3828,12 +3884,24 @@ export type UpdateApiKeyDto = { }; export type UpdateCronTriggerInput = { + /** The id of the cron trigger to update */ id: Scalars['String']; + /** The cron trigger updates */ + update: UpdateCronTriggerInputUpdates; +}; + +export type UpdateCronTriggerInputUpdates = { settings: Scalars['JSON']; }; export type UpdateDatabaseEventTriggerInput = { + /** The id of the database event trigger to update */ id: Scalars['String']; + /** The database event trigger updates */ + update: UpdateDatabaseEventTriggerInputUpdates; +}; + +export type UpdateDatabaseEventTriggerInputUpdates = { settings: Scalars['JSON']; }; @@ -3957,11 +4025,29 @@ export type UpdateRolePayload = { label?: InputMaybe; }; +export type UpdateRouteTriggerInput = { + /** The id of the route to update */ + id: Scalars['String']; + /** The route updates */ + update: UpdateRouteTriggerInputUpdates; +}; + +export type UpdateRouteTriggerInputUpdates = { + httpMethod: HttpMethod; + isAuthRequired: Scalars['Boolean']; + path: Scalars['String']; +}; + export type UpdateServerlessFunctionInput = { + /** Id of the serverless function to update */ + id: Scalars['UUID']; + /** The serverless function updates */ + update: UpdateServerlessFunctionInputUpdates; +}; + +export type UpdateServerlessFunctionInputUpdates = { code: Scalars['JSON']; description?: InputMaybe; - /** Id of the serverless function to execute */ - id: Scalars['UUID']; name: Scalars['String']; timeoutSeconds?: InputMaybe; }; diff --git a/packages/twenty-front/src/generated/graphql.ts b/packages/twenty-front/src/generated/graphql.ts index 3c5f5fd11a9..e42ef690c26 100644 --- a/packages/twenty-front/src/generated/graphql.ts +++ b/packages/twenty-front/src/generated/graphql.ts @@ -1363,6 +1363,14 @@ export type GridPositionInput = { rowSpan: Scalars['Float']; }; +export enum HttpMethod { + DELETE = 'DELETE', + GET = 'GET', + PATCH = 'PATCH', + POST = 'POST', + PUT = 'PUT' +} + export enum HealthIndicatorId { app = 'app', connectedAccount = 'connectedAccount', @@ -3322,6 +3330,18 @@ export type Role = { workspaceMembers: Array; }; +export type RouteTrigger = { + __typename?: 'RouteTrigger'; + createdAt: Scalars['DateTime']; + httpMethod: HttpMethod; + id: Scalars['ID']; + isAuthRequired: Scalars['Boolean']; + path: Scalars['String']; + serverlessFunctionId: Scalars['String']; + updatedAt: Scalars['DateTime']; + workspaceId: Scalars['String']; +}; + export type RunWorkflowVersionInput = { /** Execution result in JSON format */ payload?: InputMaybe; @@ -3674,12 +3694,24 @@ export type UpdateApiKeyDto = { }; export type UpdateCronTriggerInput = { + /** The id of the cron trigger to update */ id: Scalars['String']; + /** The cron trigger updates */ + update: UpdateCronTriggerInputUpdates; +}; + +export type UpdateCronTriggerInputUpdates = { settings: Scalars['JSON']; }; export type UpdateDatabaseEventTriggerInput = { + /** The id of the database event trigger to update */ id: Scalars['String']; + /** The database event trigger updates */ + update: UpdateDatabaseEventTriggerInputUpdates; +}; + +export type UpdateDatabaseEventTriggerInputUpdates = { settings: Scalars['JSON']; }; @@ -3796,10 +3828,15 @@ export type UpdateRolePayload = { }; export type UpdateServerlessFunctionInput = { + /** Id of the serverless function to update */ + id: Scalars['UUID']; + /** The serverless function updates */ + update: UpdateServerlessFunctionInputUpdates; +}; + +export type UpdateServerlessFunctionInputUpdates = { code: Scalars['JSON']; description?: InputMaybe; - /** Id of the serverless function to execute */ - id: Scalars['UUID']; name: Scalars['String']; timeoutSeconds?: InputMaybe; }; diff --git a/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useUpdateOneServerlessFunction.ts b/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useUpdateOneServerlessFunction.ts index 473b770d230..be7fab22245 100644 --- a/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useUpdateOneServerlessFunction.ts +++ b/packages/twenty-front/src/modules/settings/serverless-functions/hooks/useUpdateOneServerlessFunction.ts @@ -1,13 +1,13 @@ import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient'; import { UPDATE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/updateOneServerlessFunction'; +import { FIND_ONE_SERVERLESS_FUNCTION_SOURCE_CODE } from '@/settings/serverless-functions/graphql/queries/findOneServerlessFunctionSourceCode'; import { useMutation } from '@apollo/client'; +import { getOperationName } from '@apollo/client/utilities'; import { type UpdateOneServerlessFunctionMutation, type UpdateOneServerlessFunctionMutationVariables, - type UpdateServerlessFunctionInput, + type UpdateServerlessFunctionInputUpdates, } from '~/generated-metadata/graphql'; -import { getOperationName } from '@apollo/client/utilities'; -import { FIND_ONE_SERVERLESS_FUNCTION_SOURCE_CODE } from '@/settings/serverless-functions/graphql/queries/findOneServerlessFunctionSourceCode'; export const useUpdateOneServerlessFunction = ( serverlessFunctionId: string, @@ -21,11 +21,11 @@ export const useUpdateOneServerlessFunction = ( }); const updateOneServerlessFunction = async ( - input: Omit, + update: UpdateServerlessFunctionInputUpdates, ) => { return await mutate({ variables: { - input: { ...input, id: serverlessFunctionId }, + input: { update, id: serverlessFunctionId }, }, refetchQueries: [ getOperationName(FIND_ONE_SERVERLESS_FUNCTION_SOURCE_CODE) ?? '', diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx index 2f740008de3..faec8029bf7 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/code-action/components/WorkflowEditActionServerlessFunction.tsx @@ -38,6 +38,7 @@ import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; +import { SOURCE_FOLDER_NAME } from '@/serverless-functions/constants/SourceFolderName'; import { WorkflowActionFooter } from '@/workflow/workflow-steps/components/WorkflowActionFooter'; import { type Monaco } from '@monaco-editor/react'; import { type editor } from 'monaco-editor'; @@ -50,7 +51,6 @@ import { IconCode, IconPlayerPlay, useIcons } from 'twenty-ui/display'; import { CodeEditor } from 'twenty-ui/input'; import { useIsMobile } from 'twenty-ui/utilities'; import { useDebouncedCallback } from 'use-debounce'; -import { SOURCE_FOLDER_NAME } from '@/serverless-functions/constants/SourceFolderName'; const CODE_EDITOR_MIN_HEIGHT = 343; diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/common/1759417994272-setServerlessFunctionIdInTriggersNonNullable.ts b/packages/twenty-server/src/database/typeorm/core/migrations/common/1759417994272-setServerlessFunctionIdInTriggersNonNullable.ts new file mode 100644 index 00000000000..278923140e9 --- /dev/null +++ b/packages/twenty-server/src/database/typeorm/core/migrations/common/1759417994272-setServerlessFunctionIdInTriggersNonNullable.ts @@ -0,0 +1,67 @@ +import { type MigrationInterface, type QueryRunner } from 'typeorm'; + +export class SetServerlessFunctionIdInTriggersNonNullable1759417994272 + implements MigrationInterface +{ + name = 'SetServerlessFunctionIdInTriggersNonNullable1759417994272'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."cronTrigger" DROP CONSTRAINT "FK_f70831ec336e0cb42d6a33b80ba"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."cronTrigger" ALTER COLUMN "serverlessFunctionId" SET NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "core"."databaseEventTrigger" DROP CONSTRAINT "FK_7650f1b8b693cde204f44ab0aa4"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."databaseEventTrigger" ALTER COLUMN "serverlessFunctionId" SET NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "core"."route" DROP CONSTRAINT "FK_c63b1110bbf09051be2f495d0be"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."route" ALTER COLUMN "serverlessFunctionId" SET NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "core"."cronTrigger" ADD CONSTRAINT "FK_f70831ec336e0cb42d6a33b80ba" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "core"."databaseEventTrigger" ADD CONSTRAINT "FK_7650f1b8b693cde204f44ab0aa4" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "core"."route" ADD CONSTRAINT "FK_c63b1110bbf09051be2f495d0be" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."route" DROP CONSTRAINT "FK_c63b1110bbf09051be2f495d0be"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."databaseEventTrigger" DROP CONSTRAINT "FK_7650f1b8b693cde204f44ab0aa4"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."cronTrigger" DROP CONSTRAINT "FK_f70831ec336e0cb42d6a33b80ba"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."route" ALTER COLUMN "serverlessFunctionId" DROP NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "core"."route" ADD CONSTRAINT "FK_c63b1110bbf09051be2f495d0be" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "core"."databaseEventTrigger" ALTER COLUMN "serverlessFunctionId" DROP NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "core"."databaseEventTrigger" ADD CONSTRAINT "FK_7650f1b8b693cde204f44ab0aa4" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "core"."cronTrigger" ALTER COLUMN "serverlessFunctionId" DROP NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE "core"."cronTrigger" ADD CONSTRAINT "FK_f70831ec336e0cb42d6a33b80ba" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } +} diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/common/1759418198310-renameRouteToRouteTrigger.ts b/packages/twenty-server/src/database/typeorm/core/migrations/common/1759418198310-renameRouteToRouteTrigger.ts new file mode 100644 index 00000000000..d943f1c479a --- /dev/null +++ b/packages/twenty-server/src/database/typeorm/core/migrations/common/1759418198310-renameRouteToRouteTrigger.ts @@ -0,0 +1,55 @@ +import { type MigrationInterface, type QueryRunner } from 'typeorm'; + +export class RenameRouteToRouteTrigger1759418198310 + implements MigrationInterface +{ + name = 'RenameRouteToRouteTrigger1759418198310'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."route" RENAME TO "routeTrigger"`, + ); + await queryRunner.query( + `ALTER TYPE "core"."route_httpmethod_enum" RENAME TO "routeTrigger_httpmethod_enum"`, + ); + await queryRunner.query( + `ALTER INDEX "core"."IDX_1c39502392dd9cbb186deba158" RENAME TO "IDX_e9c53b9ac5035d3202a8737020"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."routeTrigger" DROP CONSTRAINT "FK_c63b1110bbf09051be2f495d0be"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."routeTrigger" DROP CONSTRAINT "IDX_ROUTE_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."routeTrigger" ADD CONSTRAINT "IDX_ROUTE_TRIGGER_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE" UNIQUE ("path", "httpMethod", "workspaceId")`, + ); + await queryRunner.query( + `ALTER TABLE "core"."routeTrigger" ADD CONSTRAINT "FK_c89ed9d929873119478fc0d9cc5" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."routeTrigger" DROP CONSTRAINT "FK_c89ed9d929873119478fc0d9cc5"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."routeTrigger" DROP CONSTRAINT "IDX_ROUTE_TRIGGER_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."routeTrigger" ADD CONSTRAINT "IDX_ROUTE_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE" UNIQUE ("path", "httpMethod", "workspaceId")`, + ); + await queryRunner.query( + `ALTER TABLE "core"."routeTrigger" ADD CONSTRAINT "FK_c63b1110bbf09051be2f495d0be" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER INDEX "core"."IDX_e9c53b9ac5035d3202a8737020" RENAME TO "IDX_1c39502392dd9cbb186deba158"`, + ); + await queryRunner.query( + `ALTER TYPE "core"."routeTrigger_httpmethod_enum" RENAME TO "route_httpmethod_enum"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."routeTrigger" RENAME TO "route"`, + ); + } +} diff --git a/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts b/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts index 226ca3ff127..c7d1293739e 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-sync.service.ts @@ -369,9 +369,11 @@ export class ApplicationSyncService { const updateServerlessFunctionInput = { id: serverlessFunctionToUpdate.id, - name: serverlessFunctionToSync.name, - timeoutSeconds: serverlessFunctionToSync.timeoutSeconds, - code: serverlessFunctionToSync.code, + update: { + name: serverlessFunctionToSync.name, + timeoutSeconds: serverlessFunctionToSync.timeoutSeconds, + code: serverlessFunctionToSync.code, + }, }; await this.serverlessFunctionV2Service.updateOne( @@ -505,8 +507,10 @@ export class ApplicationSyncService { const updateDatabaseEventTriggerInput = { id: triggerToUpdate.id, - settings: { - eventName: triggerToSync.eventName, + update: { + settings: { + eventName: triggerToSync.eventName, + }, }, }; @@ -616,8 +620,10 @@ export class ApplicationSyncService { const updateCronTriggerInput = { id: triggerToUpdate.id, - settings: { - pattern: triggerToSync.schedule, + update: { + settings: { + pattern: triggerToSync.schedule, + }, }, }; diff --git a/packages/twenty-server/src/engine/core-modules/common/constant/all-flat-entity-maps-properties.constant.ts b/packages/twenty-server/src/engine/core-modules/common/constant/all-flat-entity-maps-properties.constant.ts index 1ba74afaade..7a7aa753136 100644 --- a/packages/twenty-server/src/engine/core-modules/common/constant/all-flat-entity-maps-properties.constant.ts +++ b/packages/twenty-server/src/engine/core-modules/common/constant/all-flat-entity-maps-properties.constant.ts @@ -8,5 +8,6 @@ export const ALL_FLAT_ENTITY_MAPS_PROPERTIES = [ 'flatServerlessFunctionMaps', 'flatDatabaseEventTriggerMaps', 'flatCronTriggerMaps', + 'flatRouteTriggerMaps', 'flatFieldMetadataMaps', ] as const satisfies (keyof AllFlatEntityMaps)[]; diff --git a/packages/twenty-server/src/engine/core-modules/common/constant/empty-all-flat-entity-maps.constant.ts b/packages/twenty-server/src/engine/core-modules/common/constant/empty-all-flat-entity-maps.constant.ts index de943b0cd2b..7e7605fa4fe 100644 --- a/packages/twenty-server/src/engine/core-modules/common/constant/empty-all-flat-entity-maps.constant.ts +++ b/packages/twenty-server/src/engine/core-modules/common/constant/empty-all-flat-entity-maps.constant.ts @@ -10,4 +10,5 @@ export const EMPTY_ALL_FLAT_ENTITY_MAPS = { flatServerlessFunctionMaps: EMPTY_FLAT_ENTITY_MAPS, flatCronTriggerMaps: EMPTY_FLAT_ENTITY_MAPS, flatDatabaseEventTriggerMaps: EMPTY_FLAT_ENTITY_MAPS, + flatRouteTriggerMaps: EMPTY_FLAT_ENTITY_MAPS, } as const satisfies AllFlatEntityMaps; diff --git a/packages/twenty-server/src/engine/core-modules/common/types/all-flat-entities-by-metadata-engine-name.type.ts b/packages/twenty-server/src/engine/core-modules/common/types/all-flat-entities-by-metadata-engine-name.type.ts index 2d5abd88932..ff832430e5f 100644 --- a/packages/twenty-server/src/engine/core-modules/common/types/all-flat-entities-by-metadata-engine-name.type.ts +++ b/packages/twenty-server/src/engine/core-modules/common/types/all-flat-entities-by-metadata-engine-name.type.ts @@ -5,6 +5,7 @@ import { type FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/datab import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; import { type FlatIndexMetadata } from 'src/engine/metadata-modules/flat-index-metadata/types/flat-index-metadata.type'; import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type'; +import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; import { type FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type'; export type AllFlatEntitiesByMetadataEngineName = { @@ -16,4 +17,5 @@ export type AllFlatEntitiesByMetadataEngineName = { serverlessFunction: FlatServerlessFunction; cronTrigger: FlatCronTrigger; databaseEventTrigger: FlatDatabaseEventTrigger; + routeTrigger: FlatRouteTrigger; }; diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/update-cron-trigger.input.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/update-cron-trigger.input.ts index f5fa5850582..0fd4b59e62e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/update-cron-trigger.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/update-cron-trigger.input.ts @@ -1,19 +1,32 @@ import { Field, InputType } from '@nestjs/graphql'; -import { IsNotEmpty, IsObject, IsUUID } from 'class-validator'; +import { Type } from 'class-transformer'; +import { IsNotEmpty, IsObject, IsUUID, ValidateNested } from 'class-validator'; import GraphQLJSON from 'graphql-type-json'; import { CronTriggerSettings } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; @InputType() -export class UpdateCronTriggerInput { - @IsUUID() - @IsNotEmpty() - @Field(() => String) - id: string; - +class UpdateCronTriggerInputUpdates { @IsObject() @IsNotEmpty() @Field(() => GraphQLJSON) settings: CronTriggerSettings; } + +@InputType() +export class UpdateCronTriggerInput { + @IsUUID() + @IsNotEmpty() + @Field(() => String, { + description: 'The id of the cron trigger to update', + }) + id: string; + + @Type(() => UpdateCronTriggerInputUpdates) + @ValidateNested() + @Field(() => UpdateCronTriggerInputUpdates, { + description: 'The cron trigger updates', + }) + update: UpdateCronTriggerInputUpdates; +} diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity.ts index c157a70b8b5..0bb2eb81c1c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity.ts @@ -40,8 +40,8 @@ export class CronTrigger extends SyncableEntity { @JoinColumn({ name: 'serverlessFunctionId' }) serverlessFunction: Relation; - @Column({ nullable: true, type: 'uuid' }) - serverlessFunctionId: string | null; + @Column({ nullable: false, type: 'uuid' }) + serverlessFunctionId: string; @Column({ nullable: false, type: 'uuid' }) workspaceId: string; diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception.ts index c8588c31f53..06dae41062f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception.ts +++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception.ts @@ -9,4 +9,5 @@ export class CronTriggerException extends CustomException { export enum CronTriggerExceptionCode { CRON_TRIGGER_NOT_FOUND = 'CRON_TRIGGER_NOT_FOUND', CRON_TRIGGER_ALREADY_EXIST = 'CRON_TRIGGER_ALREADY_EXIST', + SERVERLESS_FUNCTION_NOT_FOUND = 'SERVERLESS_FUNCTION_NOT_FOUND', } diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service.ts index c5770e0c474..4a2b772968a 100644 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service.ts @@ -36,7 +36,7 @@ export class CronTriggerV2Service { await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatEntities: ['flatCronTriggerMaps'], + flatEntities: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'], }, ); @@ -64,6 +64,10 @@ export class CronTriggerV2Service { to: toFlatCronTriggerMaps, }, }, + dependencyAllFlatEntityMaps: { + flatServerlessFunctionMaps: + flatEntityMaps.flatServerlessFunctionMaps, + }, buildOptions: { isSystemBuild: false, inferDeletionFromMissingEntities: false, @@ -82,7 +86,7 @@ export class CronTriggerV2Service { await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatEntities: ['flatCronTriggerMaps'], + flatEntities: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'], }, ); @@ -100,7 +104,7 @@ export class CronTriggerV2Service { await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatEntities: ['flatCronTriggerMaps'], + flatEntities: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'], }, ); @@ -131,6 +135,10 @@ export class CronTriggerV2Service { to: toFlatCronTriggerMaps, }, }, + dependencyAllFlatEntityMaps: { + flatServerlessFunctionMaps: + flatEntityMaps.flatServerlessFunctionMaps, + }, buildOptions: { isSystemBuild: false, inferDeletionFromMissingEntities: false, @@ -166,11 +174,14 @@ export class CronTriggerV2Service { destroyCronTriggerInput: CronTriggerIdInput; workspaceId: string; }): Promise { - const { flatCronTriggerMaps: existingFlatCronTriggerMaps } = + const { + flatCronTriggerMaps: existingFlatCronTriggerMaps, + flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, + } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatEntities: ['flatCronTriggerMaps'], + flatEntities: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'], }, ); @@ -202,6 +213,9 @@ export class CronTriggerV2Service { to: toFlatCronTriggerMaps, }, }, + dependencyAllFlatEntityMaps: { + flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, + }, buildOptions: { isSystemBuild: false, inferDeletionFromMissingEntities: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-update-cron-trigger-input-to-flat-cron-trigger-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-update-cron-trigger-input-to-flat-cron-trigger-to-update-or-throw.util.ts index c4519255d29..d9e92b0bc2c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-update-cron-trigger-input-to-flat-cron-trigger-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-update-cron-trigger-input-to-flat-cron-trigger-to-update-or-throw.util.ts @@ -25,7 +25,7 @@ export const fromUpdateCronTriggerInputToFlatCronTriggerToUpdateOrThrow = ({ return { ...existingFlatCronTrigger, - settings: updateCronTriggerInput.settings, + settings: updateCronTriggerInput.update.settings, updatedAt: new Date(), }; }; diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/update-database-event-trigger.input.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/update-database-event-trigger.input.ts index 186924d258d..6cc4e408ebd 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/update-database-event-trigger.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/update-database-event-trigger.input.ts @@ -1,19 +1,32 @@ import { Field, InputType } from '@nestjs/graphql'; -import { IsNotEmpty, IsObject, IsUUID } from 'class-validator'; +import { Type } from 'class-transformer'; +import { IsNotEmpty, IsObject, IsUUID, ValidateNested } from 'class-validator'; import GraphQLJSON from 'graphql-type-json'; import { DatabaseEventTriggerSettings } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; @InputType() -export class UpdateDatabaseEventTriggerInput { - @IsUUID() - @IsNotEmpty() - @Field() - id: string; - +class UpdateDatabaseEventTriggerInputUpdates { @IsObject() @IsNotEmpty() @Field(() => GraphQLJSON) settings: DatabaseEventTriggerSettings; } + +@InputType() +export class UpdateDatabaseEventTriggerInput { + @IsUUID() + @IsNotEmpty() + @Field({ + description: 'The id of the database event trigger to update', + }) + id: string; + + @Type(() => UpdateDatabaseEventTriggerInputUpdates) + @ValidateNested() + @Field(() => UpdateDatabaseEventTriggerInputUpdates, { + description: 'The database event trigger updates', + }) + update: UpdateDatabaseEventTriggerInputUpdates; +} diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity.ts index d5e6f2648df..38401f71046 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity.ts @@ -43,8 +43,8 @@ export class DatabaseEventTrigger @JoinColumn({ name: 'serverlessFunctionId' }) serverlessFunction: Relation; - @Column({ nullable: true, type: 'uuid' }) - serverlessFunctionId: string | null; + @Column({ nullable: false, type: 'uuid' }) + serverlessFunctionId: string; @Column({ nullable: false, type: 'uuid' }) workspaceId: string; diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception.ts index c4123b41433..87f3d8b0f7a 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception.ts @@ -9,4 +9,6 @@ export class DatabaseEventTriggerException extends CustomException { export enum DatabaseEventTriggerExceptionCode { DATABASE_EVENT_TRIGGER_NOT_FOUND = 'DATABASE_EVENT_TRIGGER_NOT_FOUND', DATABASE_EVENT_TRIGGER_ALREADY_EXIST = 'DATABASE_EVENT_TRIGGER_ALREADY_EXIST', + DATABASE_EVENT_TRIGGER_INVALID = 'DATABASE_EVENT_TRIGGER_INVALID', + SERVERLESS_FUNCTION_NOT_FOUND = 'SERVERLESS_FUNCTION_NOT_FOUND', } diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service.ts index d743637d68c..0bf295062a3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service.ts @@ -36,7 +36,10 @@ export class DatabaseEventTriggerV2Service { await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatEntities: ['flatDatabaseEventTriggerMaps'], + flatEntities: [ + 'flatDatabaseEventTriggerMaps', + 'flatServerlessFunctionMaps', + ], }, ); @@ -66,6 +69,10 @@ export class DatabaseEventTriggerV2Service { to: toFlatDatabaseEventTriggerMaps, }, }, + dependencyAllFlatEntityMaps: { + flatServerlessFunctionMaps: + flatEntityMaps.flatServerlessFunctionMaps, + }, buildOptions: { isSystemBuild: false, inferDeletionFromMissingEntities: false, @@ -105,7 +112,10 @@ export class DatabaseEventTriggerV2Service { await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatEntities: ['flatDatabaseEventTriggerMaps'], + flatEntities: [ + 'flatDatabaseEventTriggerMaps', + 'flatServerlessFunctionMaps', + ], }, ); @@ -140,6 +150,10 @@ export class DatabaseEventTriggerV2Service { to: toFlatDatabaseEventTriggerMaps, }, }, + dependencyAllFlatEntityMaps: { + flatServerlessFunctionMaps: + flatEntityMaps.flatServerlessFunctionMaps, + }, buildOptions: { isSystemBuild: false, inferDeletionFromMissingEntities: false, @@ -180,11 +194,15 @@ export class DatabaseEventTriggerV2Service { }): Promise { const { flatDatabaseEventTriggerMaps: existingFlatDatabaseEventTriggerMaps, + flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatEntities: ['flatDatabaseEventTriggerMaps'], + flatEntities: [ + 'flatDatabaseEventTriggerMaps', + 'flatServerlessFunctionMaps', + ], }, ); @@ -219,6 +237,9 @@ export class DatabaseEventTriggerV2Service { to: toFlatDatabaseEventTriggerMaps, }, }, + dependencyAllFlatEntityMaps: { + flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, + }, buildOptions: { isSystemBuild: false, inferDeletionFromMissingEntities: true, diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-update-database-event-trigger-input-to-flat-database-event-trigger-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-update-database-event-trigger-input-to-flat-database-event-trigger-to-update-or-throw.util.ts index 6ee92f6ae4b..86343902988 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-update-database-event-trigger-input-to-flat-database-event-trigger-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-update-database-event-trigger-input-to-flat-database-event-trigger-to-update-or-throw.util.ts @@ -26,7 +26,7 @@ export const fromUpdateDatabaseEventTriggerInputToFlatDatabaseEventTriggerToUpda return { ...existingFlatDatabaseEventTrigger, - settings: updateDatabaseEventTriggerInput.settings, + settings: updateDatabaseEventTriggerInput.update.settings, updatedAt: new Date(), }; }; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/throw-on-field-input-transpilations-error.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/throw-on-field-input-transpilations-error.util.ts index 05fe43643d3..7feac8c3cfa 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/throw-on-field-input-transpilations-error.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/throw-on-field-input-transpilations-error.util.ts @@ -38,6 +38,7 @@ export const throwOnFieldInputTranspilationsError: ThrowOnFieldInputTranspilatio serverlessFunction: [], databaseEventTrigger: [], cronTrigger: [], + routeTrigger: [], }, status: 'fail', }, diff --git a/packages/twenty-server/src/engine/metadata-modules/metadata-engine.module.ts b/packages/twenty-server/src/engine/metadata-modules/metadata-engine.module.ts index fc91523bf54..53e14f34379 100644 --- a/packages/twenty-server/src/engine/metadata-modules/metadata-engine.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/metadata-engine.module.ts @@ -13,7 +13,7 @@ import { SearchFieldMetadataModule } from 'src/engine/metadata-modules/search-fi import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module'; import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module'; import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module'; -import { RouteModule } from 'src/engine/metadata-modules/route/route.module'; +import { RouteTriggerModule } from 'src/engine/metadata-modules/route-trigger/route-trigger.module'; import { ServerlessFunctionLayerModule } from 'src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.module'; @Module({ @@ -30,7 +30,7 @@ import { ServerlessFunctionLayerModule } from 'src/engine/metadata-modules/serve RemoteServerModule, RoleModule, PermissionsModule, - RouteModule, + RouteTriggerModule, CronTriggerModule, DatabaseEventTriggerModule, ], diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-editable-properties.constant.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-editable-properties.constant.ts new file mode 100644 index 00000000000..5283053e3b6 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-editable-properties.constant.ts @@ -0,0 +1,7 @@ +import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; + +export const FLAT_ROUTE_TRIGGER_EDITABLE_PROPERTIES = [ + 'path', + 'isAuthRequired', + 'httpMethod', +] as const satisfies (keyof FlatRouteTrigger)[]; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-properties-to-compare.constant.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-properties-to-compare.constant.ts new file mode 100644 index 00000000000..cf6efc641b0 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-properties-to-compare.constant.ts @@ -0,0 +1,6 @@ +import { FLAT_ROUTE_TRIGGER_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-editable-properties.constant'; +import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; + +export const FLAT_ROUTE_TRIGGER_PROPERTIES_TO_COMPARE = [ + ...FLAT_ROUTE_TRIGGER_EDITABLE_PROPERTIES, +] as const satisfies (keyof FlatRouteTrigger)[]; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input.ts new file mode 100644 index 00000000000..54d5d0fdbfd --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input.ts @@ -0,0 +1,37 @@ +import { Field, HideField, InputType } from '@nestjs/graphql'; + +import { + IsBoolean, + IsEnum, + IsNotEmpty, + IsString, + IsUUID, +} from 'class-validator'; + +import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; + +@InputType() +export class CreateRouteTriggerInput { + @IsString() + @IsNotEmpty() + @Field() + path: string; + + @IsBoolean() + @IsNotEmpty() + @Field({ defaultValue: true }) + isAuthRequired: boolean; + + @IsEnum(HTTPMethod) + @IsNotEmpty() + @Field(() => HTTPMethod, { defaultValue: HTTPMethod.GET }) + httpMethod: HTTPMethod; + + @IsUUID() + @IsNotEmpty() + @Field() + serverlessFunctionId: string; + + @HideField() + universalIdentifier?: string; +} diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input.ts new file mode 100644 index 00000000000..b17e2d03e12 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input.ts @@ -0,0 +1,11 @@ +import { Field, InputType } from '@nestjs/graphql'; + +import { IsNotEmpty, IsUUID } from 'class-validator'; + +@InputType() +export class RouteTriggerIdInput { + @IsUUID() + @IsNotEmpty() + @Field() + id: string; +} diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto.ts new file mode 100644 index 00000000000..35142de4059 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto.ts @@ -0,0 +1,32 @@ +import { Field, ID, ObjectType, registerEnumType } from '@nestjs/graphql'; + +import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; + +registerEnumType(HTTPMethod, { name: 'HTTPMethod' }); + +@ObjectType('RouteTrigger') +export class RouteTriggerDTO { + @Field(() => ID) + id: string; + + @Field() + path: string; + + @Field() + isAuthRequired: boolean; + + @Field(() => HTTPMethod) + httpMethod: HTTPMethod; + + @Field() + serverlessFunctionId: string; + + @Field() + workspaceId: string; + + @Field() + createdAt: Date; + + @Field() + updatedAt: Date; +} diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input.ts new file mode 100644 index 00000000000..89f846d66c3 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input.ts @@ -0,0 +1,48 @@ +import { Field, InputType } from '@nestjs/graphql'; + +import { Type } from 'class-transformer'; +import { + IsBoolean, + IsEnum, + IsNotEmpty, + IsString, + IsUUID, + ValidateNested, +} from 'class-validator'; + +import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; + +@InputType() +class UpdateRouteTriggerInputUpdates { + @IsString() + @IsNotEmpty() + @Field() + path: string; + + @IsBoolean() + @IsNotEmpty() + @Field() + isAuthRequired: boolean; + + @IsEnum(HTTPMethod) + @IsNotEmpty() + @Field(() => HTTPMethod) + httpMethod: HTTPMethod; +} + +@InputType() +export class UpdateRouteTriggerInput { + @IsUUID() + @IsNotEmpty() + @Field({ + description: 'The id of the route to update', + }) + id: string; + + @Type(() => UpdateRouteTriggerInputUpdates) + @ValidateNested() + @Field(() => UpdateRouteTriggerInputUpdates, { + description: 'The route updates', + }) + update: UpdateRouteTriggerInputUpdates; +} diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception.ts new file mode 100644 index 00000000000..b4af040d57e --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception.ts @@ -0,0 +1,16 @@ +import { CustomException } from 'src/utils/custom-exception'; + +export class RouteTriggerException extends CustomException { + code: RouteTriggerExceptionCode; + constructor(message: string, code: RouteTriggerExceptionCode) { + super(message, code); + } +} + +export enum RouteTriggerExceptionCode { + ROUTE_NOT_FOUND = 'ROUTE_NOT_FOUND', + ROUTE_ALREADY_EXIST = 'ROUTE_ALREADY_EXIST', + ROUTE_INVALID = 'ROUTE_INVALID', + ROUTE_PATH_ALREADY_EXIST = 'ROUTE_PATH_ALREADY_EXIST', + SERVERLESS_FUNCTION_NOT_FOUND = 'SERVERLESS_FUNCTION_NOT_FOUND', +} diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts new file mode 100644 index 00000000000..110e2e59b29 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts @@ -0,0 +1,99 @@ +import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; +import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; +import { InjectRepository } from '@nestjs/typeorm'; + +import { Repository } from 'typeorm'; + +import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter'; +import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; +import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; +import { CreateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input'; +import { RouteTriggerIdInput } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input'; +import { RouteTriggerDTO } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto'; +import { UpdateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input'; +import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { RouteTriggerV2Service } from 'src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service'; +import { routeTriggerGraphQLApiExceptionHandler } from 'src/engine/metadata-modules/route-trigger/utils/route-trigger-graphql-api-exception-handler.utils'; + +@UseGuards(WorkspaceAuthGuard) +@Resolver() +@UsePipes(ResolverValidationPipe) +@UseFilters(PreventNestToAutoLogGraphqlErrorsFilter) +export class RouteTriggerResolver { + constructor( + private readonly routeV2Service: RouteTriggerV2Service, + @InjectRepository(RouteTrigger) + private readonly routeTriggerRepository: Repository, + ) {} + + @Query(() => RouteTriggerDTO) + async findOneRouteTrigger( + @Args('input') { id }: RouteTriggerIdInput, + @AuthWorkspace() { id: workspaceId }: Workspace, + ) { + try { + return await this.routeTriggerRepository.findOneOrFail({ + where: { + id, + workspaceId, + }, + }); + } catch (error) { + routeTriggerGraphQLApiExceptionHandler(error); + } + } + + @Query(() => [RouteTriggerDTO]) + async findManyRouteTriggers(@AuthWorkspace() { id: workspaceId }: Workspace) { + try { + return await this.routeTriggerRepository.find({ + where: { workspaceId }, + }); + } catch (error) { + routeTriggerGraphQLApiExceptionHandler(error); + } + } + + @Mutation(() => RouteTriggerDTO) + async deleteOneRouteTrigger( + @Args('input') input: RouteTriggerIdInput, + @AuthWorkspace() { id: workspaceId }: Workspace, + ) { + try { + return await this.routeV2Service.destroyOne({ + destroyRouteInput: input, + workspaceId, + }); + } catch (error) { + routeTriggerGraphQLApiExceptionHandler(error); + } + } + + @Mutation(() => RouteTriggerDTO) + async updateOneRouteTrigger( + @Args('input') + input: UpdateRouteTriggerInput, + @AuthWorkspace() { id: workspaceId }: Workspace, + ) { + try { + return await this.routeV2Service.updateOne(input, workspaceId); + } catch (error) { + routeTriggerGraphQLApiExceptionHandler(error); + } + } + + @Mutation(() => RouteTriggerDTO) + async createOneRouteTrigger( + @Args('input') + input: CreateRouteTriggerInput, + @AuthWorkspace() { id: workspaceId }: Workspace, + ) { + try { + return await this.routeV2Service.createOne(input, workspaceId); + } catch (error) { + routeTriggerGraphQLApiExceptionHandler(error); + } + } +} diff --git a/packages/twenty-server/src/engine/metadata-modules/route/route.controller.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.controller.ts similarity index 63% rename from packages/twenty-server/src/engine/metadata-modules/route/route.controller.ts rename to packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.controller.ts index 6814d4e5261..2427566b9d2 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route/route.controller.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.controller.ts @@ -12,20 +12,20 @@ import { import { Request } from 'express'; -import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard'; -import { RouteService } from 'src/engine/metadata-modules/route/route.service'; -import { HTTPMethod } from 'src/engine/metadata-modules/route/route.entity'; import { RestApiExceptionFilter } from 'src/engine/api/rest/rest-api-exception.filter'; +import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard'; +import { HTTPMethod } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { RouteTriggerService } from 'src/engine/metadata-modules/route-trigger/route-trigger.service'; @Controller('s') @UseGuards(PublicEndpointGuard) @UseFilters(RestApiExceptionFilter) -export class RouteController { - constructor(private readonly routeService: RouteService) {} +export class RouteTriggerController { + constructor(private readonly routeTriggerService: RouteTriggerService) {} @Get('*') async get(@Req() request: Request) { - return await this.routeService.handle({ + return await this.routeTriggerService.handle({ request, httpMethod: HTTPMethod.GET, }); @@ -33,7 +33,7 @@ export class RouteController { @Post('*') async post(@Req() request: Request) { - return await this.routeService.handle({ + return await this.routeTriggerService.handle({ request, httpMethod: HTTPMethod.POST, }); @@ -41,7 +41,7 @@ export class RouteController { @Put('*') async put(@Req() request: Request) { - return await this.routeService.handle({ + return await this.routeTriggerService.handle({ request, httpMethod: HTTPMethod.PUT, }); @@ -49,7 +49,7 @@ export class RouteController { @Patch('*') async patch(@Req() request: Request) { - return await this.routeService.handle({ + return await this.routeTriggerService.handle({ request, httpMethod: HTTPMethod.PATCH, }); @@ -57,7 +57,7 @@ export class RouteController { @Delete('*') async delete(@Req() request: Request) { - return await this.routeService.handle({ + return await this.routeTriggerService.handle({ request, httpMethod: HTTPMethod.DELETE, }); diff --git a/packages/twenty-server/src/engine/metadata-modules/route/route.entity.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts similarity index 66% rename from packages/twenty-server/src/engine/metadata-modules/route/route.entity.ts rename to packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts index 44e717d5ffc..418d4abefc9 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route/route.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts @@ -6,12 +6,13 @@ import { ManyToOne, PrimaryGeneratedColumn, Relation, - UpdateDateColumn, Unique, + UpdateDateColumn, } from 'typeorm'; import { SyncableEntity } from 'src/engine/workspace-manager/workspace-sync/interfaces/syncable-entity.interface'; +import { RouteTriggerEntityRelationProperties } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; export enum HTTPMethod { @@ -22,13 +23,20 @@ export enum HTTPMethod { DELETE = 'DELETE', } -@Entity({ name: 'route', schema: 'core' }) -@Unique('IDX_ROUTE_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE', [ +export const ROUTE_TRIGGER_ENTITY_RELATION_PROPERTIES = [ + 'serverlessFunction', +] as const satisfies readonly RouteTriggerEntityRelationProperties[]; + +@Entity({ name: 'routeTrigger', schema: 'core' }) +@Unique('IDX_ROUTE_TRIGGER_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE', [ 'path', 'httpMethod', 'workspaceId', ]) -export class Route extends SyncableEntity { +export class RouteTrigger + extends SyncableEntity + implements Required +{ @PrimaryGeneratedColumn('uuid') id: string; @@ -48,12 +56,15 @@ export class Route extends SyncableEntity { @ManyToOne( () => ServerlessFunctionEntity, - (serverlessFunction) => serverlessFunction.routes, + (serverlessFunction) => serverlessFunction.routeTriggers, { onDelete: 'CASCADE' }, ) @JoinColumn({ name: 'serverlessFunctionId' }) serverlessFunction: Relation; + @Column({ nullable: false, type: 'uuid' }) + serverlessFunctionId: string; + @Column({ nullable: false, type: 'uuid' }) workspaceId: string; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.module.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.module.ts new file mode 100644 index 00000000000..b35721aa864 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.module.ts @@ -0,0 +1,34 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; +import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/core-modules/common/services/workspace-many-or-all-flat-entity-maps-cache.module'; +import { DomainManagerModule } from 'src/engine/core-modules/domain-manager/domain-manager.module'; +import { RouteTriggerResolver } from 'src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver'; +import { RouteTriggerController } from 'src/engine/metadata-modules/route-trigger/route-trigger.controller'; +import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { RouteTriggerService } from 'src/engine/metadata-modules/route-trigger/route-trigger.service'; +import { RouteTriggerV2Service } from 'src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service'; +import { WorkspaceFlatRouteTriggerMapCacheService } from 'src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service'; +import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module'; +import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([RouteTrigger]), + AuthModule, + DomainManagerModule, + ServerlessFunctionModule, + WorkspaceManyOrAllFlatEntityMapsCacheModule, + WorkspaceMigrationV2Module, + ], + controllers: [RouteTriggerController], + providers: [ + RouteTriggerService, + RouteTriggerV2Service, + WorkspaceFlatRouteTriggerMapCacheService, + RouteTriggerResolver, + ], + exports: [RouteTriggerV2Service, WorkspaceFlatRouteTriggerMapCacheService], +}) +export class RouteTriggerModule {} diff --git a/packages/twenty-server/src/engine/metadata-modules/route/route.service.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts similarity index 68% rename from packages/twenty-server/src/engine/metadata-modules/route/route.service.ts rename to packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts index 1ce621fd55b..1defb99ad8a 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route/route.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts @@ -12,8 +12,8 @@ import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils'; import { HTTPMethod, - Route, -} from 'src/engine/metadata-modules/route/route.entity'; + RouteTrigger, +} from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { AccessTokenService } from 'src/engine/core-modules/auth/token/services/access-token.service'; import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service'; import { @@ -23,23 +23,23 @@ import { import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service'; @Injectable() -export class RouteService { +export class RouteTriggerService { constructor( private readonly accessTokenService: AccessTokenService, private readonly serverlessFunctionService: ServerlessFunctionService, private readonly domainManagerService: DomainManagerService, - @InjectRepository(Route) - private readonly routeRepository: Repository, + @InjectRepository(RouteTrigger) + private readonly routeTriggerRepository: Repository, ) {} - private async getOneRouteWithPathParamsOrFail({ + private async getOneRouteTriggerWithPathParamsOrFail({ request, httpMethod, }: { request: Request; httpMethod: HTTPMethod; }): Promise<{ - route: Route; + routeTrigger: RouteTrigger; pathParams: Partial>; }> { const host = `${request.protocol}://${request.get('host')}`; @@ -57,7 +57,7 @@ export class RouteService { ), ); - const routes = await this.routeRepository.find({ + const routeTriggers = await this.routeTriggerRepository.find({ where: { httpMethod, workspaceId: workspace.id, @@ -67,19 +67,21 @@ export class RouteService { const requestPath = request.path.replace(/^\/s\//, '/'); - for (const route of routes) { - const routeMatcher = match(route.path, { decode: decodeURIComponent }); - const routeMatched = routeMatcher(requestPath); + for (const routeTrigger of routeTriggers) { + const routeTriggerMatcher = match(routeTrigger.path, { + decode: decodeURIComponent, + }); + const routeTriggerMatched = routeTriggerMatcher(requestPath); - if (routeMatched) { + if (routeTriggerMatched) { return { - route, - pathParams: routeMatched.params, + routeTrigger, + pathParams: routeTriggerMatched.params, }; } } - throw new NotFoundException('No Route found'); + throw new NotFoundException('No Route trigger found'); } private async validateWorkspaceFromRequest({ @@ -108,15 +110,16 @@ export class RouteService { request: Request; httpMethod: HTTPMethod; }) { - const routeWithPathParams = await this.getOneRouteWithPathParamsOrFail({ - request, - httpMethod, - }); + const routeTriggerWithPathParams = + await this.getOneRouteTriggerWithPathParamsOrFail({ + request, + httpMethod, + }); - if (routeWithPathParams.route.isAuthRequired) { + if (routeTriggerWithPathParams.routeTrigger.isAuthRequired) { await this.validateWorkspaceFromRequest({ request, - workspaceId: routeWithPathParams.route.workspaceId, + workspaceId: routeTriggerWithPathParams.routeTrigger.workspaceId, }); } @@ -127,12 +130,12 @@ export class RouteService { const executionParams = { ...queryParams, ...bodyParams, - ...routeWithPathParams.pathParams, + ...routeTriggerWithPathParams.pathParams, }; return await this.serverlessFunctionService.executeOneServerlessFunction( - routeWithPathParams.route.serverlessFunction.id, - routeWithPathParams.route.workspaceId, + routeTriggerWithPathParams.routeTrigger.serverlessFunction.id, + routeTriggerWithPathParams.routeTrigger.workspaceId, executionParams, 'draft', ); diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service.ts new file mode 100644 index 00000000000..bd20f5d5026 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service.ts @@ -0,0 +1,228 @@ +import { Injectable } from '@nestjs/common'; + +import { isDefined } from 'twenty-shared/utils'; + +import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/core-modules/common/services/workspace-many-or-all-flat-entity-maps-cache.service'; +import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/add-flat-entity-to-flat-entity-maps-or-throw.util'; +import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util'; +import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; +import { getSubFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/get-sub-flat-entity-maps-or-throw.util'; +import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util'; +import { CreateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input'; +import { RouteTriggerIdInput } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input'; +import { UpdateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input'; +import { + RouteTriggerException, + RouteTriggerExceptionCode, +} from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception'; +import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; +import { fromCreateRouteTriggerInputToFlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/utils/from-create-route-trigger-input-to-flat-route-trigger.util'; +import { fromUpdateRouteTriggerInputToFlatRouteTriggerToUpdateOrThrow } from 'src/engine/metadata-modules/route-trigger/utils/from-update-route-trigger-input-to-flat-route-trigger-to-update-or-throw.util'; +import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2'; +import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service'; + +@Injectable() +export class RouteTriggerV2Service { + constructor( + private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService, + private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, + ) {} + + async createOne(routeInput: CreateRouteTriggerInput, workspaceId: string) { + const flatEntityMaps = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatEntities: ['flatRouteTriggerMaps', 'flatServerlessFunctionMaps'], + }, + ); + + const existingFlatRouteMaps = flatEntityMaps.flatRouteTriggerMaps; + + const flatRouteTriggerToCreate = + fromCreateRouteTriggerInputToFlatRouteTrigger({ + createRouteTriggerInput: routeInput, + workspaceId, + }); + + const toFlatRouteMaps = addFlatEntityToFlatEntityMapsOrThrow({ + flatEntity: flatRouteTriggerToCreate, + flatEntityMaps: existingFlatRouteMaps, + }); + + const validateAndBuildResult = + await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( + { + workspaceId, + fromToAllFlatEntityMaps: { + flatRouteTriggerMaps: { + from: existingFlatRouteMaps, + to: toFlatRouteMaps, + }, + }, + dependencyAllFlatEntityMaps: { + flatServerlessFunctionMaps: + flatEntityMaps.flatServerlessFunctionMaps, + }, + buildOptions: { + isSystemBuild: false, + inferDeletionFromMissingEntities: false, + }, + }, + ); + + if (isDefined(validateAndBuildResult)) { + throw new WorkspaceMigrationBuilderExceptionV2( + validateAndBuildResult, + 'Multiple validation errors occurred while creating route', + ); + } + + const { flatRouteTriggerMaps: recomputedExistingFlatRouteMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatEntities: ['flatRouteTriggerMaps'], + }, + ); + + return findFlatEntityByIdInFlatEntityMapsOrThrow({ + flatEntityId: flatRouteTriggerToCreate.id, + flatEntityMaps: recomputedExistingFlatRouteMaps, + }); + } + + async updateOne(routeInput: UpdateRouteTriggerInput, workspaceId: string) { + const flatEntityMaps = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatEntities: ['flatRouteTriggerMaps', 'flatServerlessFunctionMaps'], + }, + ); + + const existingFlatRouteMaps = flatEntityMaps.flatRouteTriggerMaps; + + const optimisticallyUpdatedFlatRouteTrigger = + fromUpdateRouteTriggerInputToFlatRouteTriggerToUpdateOrThrow({ + flatRouteTriggerMaps: existingFlatRouteMaps, + updateRouteTriggerInput: routeInput, + }); + + const fromFlatRouteMaps = getSubFlatEntityMapsOrThrow({ + flatEntityIds: [optimisticallyUpdatedFlatRouteTrigger.id], + flatEntityMaps: existingFlatRouteMaps, + }); + const toFlatRouteMaps = replaceFlatEntityInFlatEntityMapsOrThrow({ + flatEntity: optimisticallyUpdatedFlatRouteTrigger, + flatEntityMaps: fromFlatRouteMaps, + }); + + const validateAndBuildResult = + await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( + { + workspaceId, + fromToAllFlatEntityMaps: { + flatRouteTriggerMaps: { + from: existingFlatRouteMaps, + to: toFlatRouteMaps, + }, + }, + dependencyAllFlatEntityMaps: { + flatServerlessFunctionMaps: + flatEntityMaps.flatServerlessFunctionMaps, + }, + buildOptions: { + isSystemBuild: false, + inferDeletionFromMissingEntities: false, + }, + }, + ); + + if (isDefined(validateAndBuildResult)) { + throw new WorkspaceMigrationBuilderExceptionV2( + validateAndBuildResult, + 'Multiple validation errors occurred while updating route', + ); + } + + const { flatRouteTriggerMaps: recomputedExistingFlatRouteMaps } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatEntities: ['flatRouteTriggerMaps'], + }, + ); + + return findFlatEntityByIdInFlatEntityMapsOrThrow({ + flatEntityId: optimisticallyUpdatedFlatRouteTrigger.id, + flatEntityMaps: recomputedExistingFlatRouteMaps, + }); + } + + async destroyOne({ + destroyRouteInput, + workspaceId, + }: { + destroyRouteInput: RouteTriggerIdInput; + workspaceId: string; + }): Promise { + const { + flatRouteTriggerMaps: existingFlatRouteMaps, + flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, + } = + await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( + { + workspaceId, + flatEntities: ['flatRouteTriggerMaps', 'flatServerlessFunctionMaps'], + }, + ); + + const existingFlatRoute = existingFlatRouteMaps.byId[destroyRouteInput.id]; + + if (!isDefined(existingFlatRoute)) { + throw new RouteTriggerException( + 'Route to destroy not found', + RouteTriggerExceptionCode.ROUTE_NOT_FOUND, + ); + } + + const fromFlatRouteMaps = getSubFlatEntityMapsOrThrow({ + flatEntityIds: [existingFlatRoute.id], + flatEntityMaps: existingFlatRouteMaps, + }); + const toFlatRouteMaps = deleteFlatEntityFromFlatEntityMapsOrThrow({ + flatEntityMaps: fromFlatRouteMaps, + entityToDeleteId: existingFlatRoute.id, + }); + + const validateAndBuildResult = + await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( + { + fromToAllFlatEntityMaps: { + flatRouteTriggerMaps: { + from: fromFlatRouteMaps, + to: toFlatRouteMaps, + }, + }, + dependencyAllFlatEntityMaps: { + flatServerlessFunctionMaps: existingFlatServerlessFunctionMaps, + }, + buildOptions: { + isSystemBuild: false, + inferDeletionFromMissingEntities: true, + }, + workspaceId, + }, + ); + + if (isDefined(validateAndBuildResult)) { + throw new WorkspaceMigrationBuilderExceptionV2( + validateAndBuildResult, + 'Multiple validation errors occurred while destroying route', + ); + } + + return existingFlatRoute; + } +} diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service.ts new file mode 100644 index 00000000000..3e1019b1002 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service.ts @@ -0,0 +1,69 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; + +import { removePropertiesFromRecord } from 'twenty-shared/utils'; +import { Repository } from 'typeorm'; + +import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator'; +import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service'; +import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum'; +import { EMPTY_FLAT_ENTITY_MAPS } from 'src/engine/core-modules/common/constant/empty-flat-entity-maps.constant'; +import { FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type'; +import { + ROUTE_TRIGGER_ENTITY_RELATION_PROPERTIES, + RouteTrigger, +} from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; +import { WorkspaceFlatMapCache } from 'src/engine/workspace-flat-map-cache/decorators/workspace-flat-map-cache.decorator'; +import { WorkspaceFlatMapCacheService } from 'src/engine/workspace-flat-map-cache/services/workspace-flat-map-cache.service'; + +@Injectable() +@WorkspaceFlatMapCache('flatRouteTriggerMaps') +export class WorkspaceFlatRouteTriggerMapCacheService extends WorkspaceFlatMapCacheService< + FlatEntityMaps +> { + constructor( + @InjectCacheStorage(CacheStorageNamespace.EngineWorkspace) + cacheStorageService: CacheStorageService, + @InjectRepository(RouteTrigger) + private readonly routeTriggerRepository: Repository, + ) { + super(cacheStorageService); + } + + protected async computeFlatMap({ + workspaceId, + }: { + workspaceId: string; + }): Promise> { + const routeTriggers = await this.routeTriggerRepository.find({ + where: { + workspaceId, + }, + }); + + const flatRouteTriggerMaps = routeTriggers.reduce< + FlatEntityMaps + >((flatEntityMaps, routeTrigger) => { + const flatRouteTrigger = { + ...removePropertiesFromRecord(routeTrigger, [ + ...ROUTE_TRIGGER_ENTITY_RELATION_PROPERTIES, + ]), + universalIdentifier: routeTrigger.universalIdentifier ?? '', + } satisfies FlatRouteTrigger; + + return { + byId: { + ...flatEntityMaps.byId, + [flatRouteTrigger.id]: flatRouteTrigger, + }, + idByUniversalIdentifier: { + ...flatEntityMaps.idByUniversalIdentifier, + [flatRouteTrigger.universalIdentifier]: flatRouteTrigger.id, + }, + }; + }, EMPTY_FLAT_ENTITY_MAPS); + + return flatRouteTriggerMaps; + } +} diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger-properties-to-compare.type.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger-properties-to-compare.type.ts new file mode 100644 index 00000000000..29ea3a478e6 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger-properties-to-compare.type.ts @@ -0,0 +1,4 @@ +import { type FLAT_ROUTE_TRIGGER_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-properties-to-compare.constant'; + +export type FlatRouteTriggerPropertiesToCompare = + (typeof FLAT_ROUTE_TRIGGER_PROPERTIES_TO_COMPARE)[number]; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type.ts new file mode 100644 index 00000000000..b9099af2d4c --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type.ts @@ -0,0 +1,17 @@ +import { type Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { type RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { type ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; +import { type ExtractRecordTypeOrmRelationProperties } from 'src/engine/workspace-manager/workspace-migration-v2/types/extract-record-typeorm-relation-properties.type'; + +export type RouteTriggerEntityRelationProperties = + ExtractRecordTypeOrmRelationProperties< + RouteTrigger, + ServerlessFunctionEntity | Workspace + >; + +export type FlatRouteTrigger = Omit< + RouteTrigger, + RouteTriggerEntityRelationProperties +> & { + universalIdentifier: string; +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/compare-two-flat-route-trigger.util.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/compare-two-flat-route-trigger.util.ts new file mode 100644 index 00000000000..8cb639bec55 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/compare-two-flat-route-trigger.util.ts @@ -0,0 +1,59 @@ +import diff from 'microdiff'; +import { type FromTo } from 'twenty-shared/types'; + +import { FLAT_ROUTE_TRIGGER_PROPERTIES_TO_COMPARE } from 'src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-properties-to-compare.constant'; +import { type FlatRouteTriggerPropertiesToCompare } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger-properties-to-compare.type'; +import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; +import { type UpdateRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type'; +import { transformMetadataForComparison } from 'src/engine/workspace-manager/workspace-sync-metadata/comparators/utils/transform-metadata-for-comparison.util'; + +type GetWorkspaceMigrationUpdateRouteTriggerActionArgs = FromTo< + FlatRouteTrigger, + 'FlatRouteTrigger' +>; + +export const compareTwoFlatRouteTrigger = ({ + fromFlatRouteTrigger, + toFlatRouteTrigger, +}: GetWorkspaceMigrationUpdateRouteTriggerActionArgs) => { + const transformMetadataForComparisonParameters = { + shouldIgnoreProperty: (property: string) => + !FLAT_ROUTE_TRIGGER_PROPERTIES_TO_COMPARE.includes( + property as FlatRouteTriggerPropertiesToCompare, + ), + propertiesToStringify: [] as const, + }; + const fromCompare = transformMetadataForComparison( + fromFlatRouteTrigger, + transformMetadataForComparisonParameters, + ); + const toCompare = transformMetadataForComparison( + toFlatRouteTrigger, + transformMetadataForComparisonParameters, + ); + + const flatRouteTriggerDifferences = diff(fromCompare, toCompare); + + return flatRouteTriggerDifferences.flatMap< + UpdateRouteTriggerAction['updates'][number] + >((difference) => { + switch (difference.type) { + case 'CHANGE': { + const { oldValue, path, value } = difference; + const property = path[0] as FlatRouteTriggerPropertiesToCompare; + + return { + from: oldValue, + to: value, + property, + }; + } + case 'CREATE': + case 'REMOVE': + default: { + // Should never occurs, we should only provide null never undefined and so on + return []; + } + } + }); +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-create-route-trigger-input-to-flat-route-trigger.util.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-create-route-trigger-input-to-flat-route-trigger.util.ts new file mode 100644 index 00000000000..4a8b8db67e3 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-create-route-trigger-input-to-flat-route-trigger.util.ts @@ -0,0 +1,27 @@ +import { v4 as uuidV4 } from 'uuid'; + +import { type CreateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input'; +import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; + +export const fromCreateRouteTriggerInputToFlatRouteTrigger = ({ + createRouteTriggerInput, + workspaceId, +}: { + createRouteTriggerInput: CreateRouteTriggerInput; + workspaceId: string; +}): FlatRouteTrigger => { + const now = new Date(); + + return { + id: uuidV4(), + universalIdentifier: + createRouteTriggerInput.universalIdentifier ?? uuidV4(), + path: createRouteTriggerInput.path, + isAuthRequired: createRouteTriggerInput.isAuthRequired, + httpMethod: createRouteTriggerInput.httpMethod, + serverlessFunctionId: createRouteTriggerInput.serverlessFunctionId, + workspaceId, + createdAt: now, + updatedAt: now, + }; +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-update-route-trigger-input-to-flat-route-trigger-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-update-route-trigger-input-to-flat-route-trigger-to-update-or-throw.util.ts new file mode 100644 index 00000000000..76c73ea17ae --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-update-route-trigger-input-to-flat-route-trigger-to-update-or-throw.util.ts @@ -0,0 +1,33 @@ +import { type FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type'; +import { type UpdateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input'; +import { + RouteTriggerException, + RouteTriggerExceptionCode, +} from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception'; +import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; + +export const fromUpdateRouteTriggerInputToFlatRouteTriggerToUpdateOrThrow = ({ + flatRouteTriggerMaps, + updateRouteTriggerInput, +}: { + flatRouteTriggerMaps: FlatEntityMaps; + updateRouteTriggerInput: UpdateRouteTriggerInput; +}): FlatRouteTrigger => { + const existingFlatRouteTrigger = + flatRouteTriggerMaps.byId[updateRouteTriggerInput.id]; + + if (!existingFlatRouteTrigger) { + throw new RouteTriggerException( + 'Route not found', + RouteTriggerExceptionCode.ROUTE_NOT_FOUND, + ); + } + + return { + ...existingFlatRouteTrigger, + path: updateRouteTriggerInput.update.path, + isAuthRequired: updateRouteTriggerInput.update.isAuthRequired, + httpMethod: updateRouteTriggerInput.update.httpMethod, + updatedAt: new Date(), + }; +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/route-trigger-graphql-api-exception-handler.utils.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/route-trigger-graphql-api-exception-handler.utils.ts new file mode 100644 index 00000000000..078f6dcb788 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/route-trigger-graphql-api-exception-handler.utils.ts @@ -0,0 +1,23 @@ +import { + ConflictError, + NotFoundError, +} from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; +import { + RouteTriggerException, + RouteTriggerExceptionCode, +} from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception'; + +export const routeTriggerGraphQLApiExceptionHandler = (error: Error): void => { + if (error instanceof RouteTriggerException) { + switch (error.code) { + case RouteTriggerExceptionCode.ROUTE_NOT_FOUND: + throw new NotFoundError('Route not found'); + case RouteTriggerExceptionCode.ROUTE_ALREADY_EXIST: + throw new ConflictError('Route already exists'); + default: + throw error; + } + } + + throw error; +}; diff --git a/packages/twenty-server/src/engine/metadata-modules/route/route.module.ts b/packages/twenty-server/src/engine/metadata-modules/route/route.module.ts deleted file mode 100644 index 68c893116c2..00000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route/route.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Module } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; - -import { RouteService } from 'src/engine/metadata-modules/route/route.service'; -import { Route } from 'src/engine/metadata-modules/route/route.entity'; -import { RouteController } from 'src/engine/metadata-modules/route/route.controller'; -import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; -import { DomainManagerModule } from 'src/engine/core-modules/domain-manager/domain-manager.module'; -import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module'; - -@Module({ - imports: [ - TypeOrmModule.forFeature([Route]), - AuthModule, - DomainManagerModule, - ServerlessFunctionModule, - ], - controllers: [RouteController], - providers: [RouteService], -}) -export class RouteModule {} diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/update-serverless-function.input.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/update-serverless-function.input.ts index 0858f42aed7..1c87e18e990 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/update-serverless-function.input.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/update-serverless-function.input.ts @@ -1,5 +1,6 @@ import { Field, InputType } from '@nestjs/graphql'; +import { Type } from 'class-transformer'; import { IsNotEmpty, IsNumber, @@ -9,6 +10,7 @@ import { IsUUID, Max, Min, + ValidateNested, } from 'class-validator'; import graphqlTypeJson from 'graphql-type-json'; @@ -16,14 +18,7 @@ import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/ import { ServerlessFunctionCode } from 'src/engine/metadata-modules/serverless-function/types/serverless-function-code.type'; @InputType() -export class UpdateServerlessFunctionInput { - @Field(() => UUIDScalarType, { - description: 'Id of the serverless function to execute', - }) - @IsNotEmpty() - @IsUUID() - id: string; - +class UpdateServerlessFunctionInputUpdates { @IsString() @Field() name: string; @@ -44,3 +39,20 @@ export class UpdateServerlessFunctionInput { @IsObject() code: ServerlessFunctionCode; } + +@InputType() +export class UpdateServerlessFunctionInput { + @Field(() => UUIDScalarType, { + description: 'Id of the serverless function to update', + }) + @IsNotEmpty() + @IsUUID() + id: string; + + @Type(() => UpdateServerlessFunctionInputUpdates) + @ValidateNested() + @Field(() => UpdateServerlessFunctionInputUpdates, { + description: 'The serverless function updates', + }) + update: UpdateServerlessFunctionInputUpdates; +} diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.entity.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.entity.ts index 32ce4c9b264..91e57159917 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.entity.ts @@ -17,7 +17,7 @@ import { SyncableEntity } from 'src/engine/workspace-manager/workspace-sync/inte import { CronTrigger } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; import { DatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; -import { Route } from 'src/engine/metadata-modules/route/route.entity'; +import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { ServerlessFunctionEntityRelationProperties } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type'; import { InputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/input-schema.type'; import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; @@ -33,7 +33,7 @@ export enum ServerlessFunctionRuntime { export const SERVERLESS_FUNCTION_ENTITY_RELATION_PROPERTIES = [ 'cronTriggers', 'databaseEventTriggers', - 'routes', + 'routeTriggers', ] as const satisfies readonly ServerlessFunctionEntityRelationProperties[]; @Entity('serverlessFunction') @@ -119,10 +119,14 @@ export class ServerlessFunctionEntity ) databaseEventTriggers: DatabaseEventTrigger[]; - @OneToMany(() => Route, (route) => route.serverlessFunction, { - cascade: true, - }) - routes: Route[]; + @OneToMany( + () => RouteTrigger, + (routeTrigger) => routeTrigger.serverlessFunction, + { + cascade: true, + }, + ) + routeTriggers: RouteTrigger[]; @CreateDateColumn({ type: 'timestamptz' }) createdAt: Date; diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts index 3ba8ec2e66c..ec6703f0470 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.service.ts @@ -263,9 +263,9 @@ export class ServerlessFunctionService { await this.serverlessFunctionRepository.update( existingServerlessFunction.id, { - name: serverlessFunctionInput.name, - description: serverlessFunctionInput.description, - timeoutSeconds: serverlessFunctionInput.timeoutSeconds, + name: serverlessFunctionInput.update.name, + description: serverlessFunctionInput.update.description, + timeoutSeconds: serverlessFunctionInput.update.timeoutSeconds, }, ); @@ -275,7 +275,7 @@ export class ServerlessFunctionService { }); await this.fileStorageService.writeFolder( - serverlessFunctionInput.code, + serverlessFunctionInput.update.code, fileFolder, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts index 522d997c19e..75573aa73ee 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type.ts @@ -1,7 +1,7 @@ import { type Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { type CronTrigger } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; import { type DatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; -import { type Route } from 'src/engine/metadata-modules/route/route.entity'; +import { type RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { type ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; import { type ExtractRecordTypeOrmRelationProperties } from 'src/engine/workspace-manager/workspace-migration-v2/types/extract-record-typeorm-relation-properties.type'; import { type ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; @@ -13,7 +13,7 @@ export type ServerlessFunctionEntityRelationProperties = ServerlessFunctionEntity, | CronTrigger | DatabaseEventTrigger - | Route + | RouteTrigger | Workspace | ApplicationEntity | ServerlessFunctionLayerEntity diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-update-serverless-function-input-to-flat-serverless-function-to-update-or-throw.util.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-update-serverless-function-input-to-flat-serverless-function-to-update-or-throw.util.ts index e0542612b24..eae43c8a24f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-update-serverless-function-input-to-flat-serverless-function-to-update-or-throw.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-update-serverless-function-input-to-flat-serverless-function-to-update-or-throw.util.ts @@ -42,14 +42,14 @@ export const fromUpdateServerlessFunctionInputToFlatServerlessFunctionToUpdateOr const updatedEditableFieldProperties = { ...extractAndSanitizeObjectStringFields( { - ...rawUpdateServerlessFunctionInput, + ...rawUpdateServerlessFunctionInput.update, checksum: serverlessFunctionCreateHash( - JSON.stringify(rawUpdateServerlessFunctionInput.code), + JSON.stringify(rawUpdateServerlessFunctionInput.update.code), ), }, FLAT_SERVERLESS_FUNCTION_EDITABLE_PROPERTIES, ), - code: rawUpdateServerlessFunctionInput.code, + code: rawUpdateServerlessFunctionInput.update.code, }; return mergeUpdateInExistingRecord({ diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant.ts index 0e716bc8cc9..c2826a08805 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant.ts @@ -18,4 +18,5 @@ export const EMPTY_ORCHESTRATOR_ACTIONS_REPORT = { serverlessFunction: emptyCreatedDeletedUpdated, databaseEventTrigger: emptyCreatedDeletedUpdated, cronTrigger: emptyCreatedDeletedUpdated, + routeTrigger: emptyCreatedDeletedUpdated, } as const satisfies OrchestratorActionsReport; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/interceptors/utils/from-workspace-migration-builder-exception-to-validation-response-error.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/interceptors/utils/from-workspace-migration-builder-exception-to-validation-response-error.util.ts index d85edee8299..d5e188f83c2 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/interceptors/utils/from-workspace-migration-builder-exception-to-validation-response-error.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/interceptors/utils/from-workspace-migration-builder-exception-to-validation-response-error.util.ts @@ -13,6 +13,7 @@ export const fromWorkspaceMigrationBuilderExceptionToValidationResponseError = ( invalidServerlessFunction: 0, invalidDatabaseEventTrigger: 0, invalidCronTrigger: 0, + invalidRouteTrigger: 0, invalidFieldMetadata: 0, totalErrors: 0, }, @@ -25,6 +26,7 @@ export const fromWorkspaceMigrationBuilderExceptionToValidationResponseError = ( serverlessFunction: [], databaseEventTrigger: [], cronTrigger: [], + routeTrigger: [], }, }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service.ts index 18bf0a02f47..ca981352360 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service.ts @@ -17,6 +17,7 @@ import { WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService } from 's import { WorkspaceMigrationV2FieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/services/workspace-migration-v2-field-actions-builder.service'; import { WorkspaceMigrationV2IndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service'; import { WorkspaceMigrationV2ObjectActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/services/workspace-migration-v2-object-actions-builder.service'; +import { WorkspaceMigrationV2RouteTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service'; import { WorkspaceMigrationV2ServerlessFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/workspace-migration-v2-serverless-function-actions-builder.service'; import { WorkspaceMigrationV2ViewFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service'; import { WorkspaceMigrationV2ViewActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/workspace-migration-v2-view-actions-builder.service'; @@ -30,6 +31,7 @@ export class WorkspaceMigrationBuildOrchestratorService { private readonly workspaceMigrationV2ServerlessFunctionActionsBuilderService: WorkspaceMigrationV2ServerlessFunctionActionsBuilderService, private readonly workspaceMigrationV2DatabaseEventTriggerActionsBuilderService: WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService, private readonly workspaceMigrationV2CronTriggerActionsBuilderService: WorkspaceMigrationV2CronTriggerActionsBuilderService, + private readonly workspaceMigrationV2RouteTriggerActionsBuilderService: WorkspaceMigrationV2RouteTriggerActionsBuilderService, private readonly workspaceMigrationV2FieldActionsBuilderService: WorkspaceMigrationV2FieldActionsBuilderService, ) {} @@ -84,6 +86,7 @@ export class WorkspaceMigrationBuildOrchestratorService { serverlessFunction: [], databaseEventTrigger: [], cronTrigger: [], + routeTrigger: [], fieldMetadata: [], }; @@ -99,6 +102,7 @@ export class WorkspaceMigrationBuildOrchestratorService { flatServerlessFunctionMaps, flatDatabaseEventTriggerMaps, flatCronTriggerMaps, + flatRouteTriggerMaps, flatFieldMetadataMaps, } = fromToAllFlatEntityMaps; @@ -289,8 +293,11 @@ export class WorkspaceMigrationBuildOrchestratorService { from: fromFlatDatabaseEventTriggerMaps, to: toFlatDatabaseEventTriggerMaps, buildOptions, + dependencyOptimisticFlatEntityMaps: { + flatServerlessFunctionMaps: + optimisticAllFlatEntityMaps.flatServerlessFunctionMaps, + }, workspaceId, - dependencyOptimisticFlatEntityMaps: undefined, }, ); @@ -317,8 +324,11 @@ export class WorkspaceMigrationBuildOrchestratorService { from: fromFlatCronTriggerMaps, to: toFlatCronTriggerMaps, buildOptions, + dependencyOptimisticFlatEntityMaps: { + flatServerlessFunctionMaps: + optimisticAllFlatEntityMaps.flatServerlessFunctionMaps, + }, workspaceId, - dependencyOptimisticFlatEntityMaps: undefined, }, ); @@ -332,6 +342,36 @@ export class WorkspaceMigrationBuildOrchestratorService { } } + if (isDefined(flatRouteTriggerMaps)) { + const { from: fromFlatRouteTriggerMaps, to: toFlatRouteTriggerMaps } = + flatRouteTriggerMaps; + + const routeTriggerResult = + await this.workspaceMigrationV2RouteTriggerActionsBuilderService.validateAndBuild( + { + from: fromFlatRouteTriggerMaps, + to: toFlatRouteTriggerMaps, + buildOptions, + dependencyOptimisticFlatEntityMaps: { + flatServerlessFunctionMaps: + optimisticAllFlatEntityMaps.flatServerlessFunctionMaps, + }, + workspaceId, + }, + ); + + optimisticAllFlatEntityMaps.flatRouteTriggerMaps = + routeTriggerResult.optimisticFlatEntityMaps; + + if (routeTriggerResult.status === 'fail') { + orchestratorFailureReport.routeTrigger.push( + ...routeTriggerResult.errors, + ); + } else { + orchestratorActionsReport.routeTrigger = routeTriggerResult.actions; + } + } + const allErrors = Object.values(orchestratorFailureReport); if (allErrors.some((report) => report.length > 0)) { @@ -396,6 +436,12 @@ export class WorkspaceMigrationBuildOrchestratorService { ...aggregatedOrchestratorActionsReport.cronTrigger.created, ...aggregatedOrchestratorActionsReport.cronTrigger.updated, /// + + // Route triggers + ...orchestratorActionsReport.routeTrigger.deleted, + ...orchestratorActionsReport.routeTrigger.created, + ...orchestratorActionsReport.routeTrigger.updated, + /// ], workspaceId, }, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/types/cron-trigger-related-flat-entity-maps.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/types/cron-trigger-related-flat-entity-maps.type.ts new file mode 100644 index 00000000000..7ebf35d170a --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/types/cron-trigger-related-flat-entity-maps.type.ts @@ -0,0 +1,6 @@ +import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type'; + +export type CronTriggerRelatedFlatEntityMaps = Pick< + AllFlatEntityMaps, + 'flatServerlessFunctionMaps' +>; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service.ts index d21222e38b9..70cdc200149 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service.ts @@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common'; import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; import { compareTwoFlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/utils/compare-two-flat-cron-trigger.util'; +import { CronTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/types/cron-trigger-related-flat-entity-maps.type'; import { FlatEntityUpdateValidationArgs, FlatEntityValidationArgs, @@ -19,7 +20,7 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp 'cronTrigger', FlatCronTrigger, WorkspaceMigrationCronTriggerActionV2, - undefined + CronTriggerRelatedFlatEntityMaps > { constructor( private readonly flatCronTriggerValidatorService: FlatCronTriggerValidatorService, @@ -31,10 +32,14 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp flatEntityToValidate: flatCronTriggerToValidate, optimisticFlatEntityMaps: optimisticFlatCronTriggerMaps, dependencyOptimisticFlatEntityMaps, - }: FlatEntityValidationArgs): Promise< + }: FlatEntityValidationArgs< + FlatCronTrigger, + CronTriggerRelatedFlatEntityMaps + >): Promise< FlatEntityValidationReturnType< WorkspaceMigrationCronTriggerActionV2, - FlatCronTrigger + FlatCronTrigger, + CronTriggerRelatedFlatEntityMaps > > { const validationResult = @@ -42,6 +47,7 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp { flatCronTriggerToValidate, optimisticFlatCronTriggerMaps, + dependencyOptimisticFlatEntityMaps, }, ); @@ -66,16 +72,21 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp flatEntityToValidate: flatCronTriggerToValidate, optimisticFlatEntityMaps: optimisticFlatCronTriggerMaps, dependencyOptimisticFlatEntityMaps, - }: FlatEntityValidationArgs): Promise< + }: FlatEntityValidationArgs< + FlatCronTrigger, + CronTriggerRelatedFlatEntityMaps + >): Promise< FlatEntityValidationReturnType< WorkspaceMigrationCronTriggerActionV2, - FlatCronTrigger + FlatCronTrigger, + CronTriggerRelatedFlatEntityMaps > > { const validationResult = this.flatCronTriggerValidatorService.validateFlatCronTriggerDeletion({ flatCronTriggerToValidate, optimisticFlatCronTriggerMaps, + dependencyOptimisticFlatEntityMaps, }); if (validationResult.errors.length > 0) { @@ -99,10 +110,14 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp flatEntityUpdate: { from: fromFlatCronTrigger, to: toFlatCronTrigger }, optimisticFlatEntityMaps: optimisticFlatCronTriggerMaps, dependencyOptimisticFlatEntityMaps, - }: FlatEntityUpdateValidationArgs): Promise< + }: FlatEntityUpdateValidationArgs< + FlatCronTrigger, + CronTriggerRelatedFlatEntityMaps + >): Promise< | FlatEntityValidationReturnType< WorkspaceMigrationCronTriggerActionV2, - FlatCronTrigger + FlatCronTrigger, + CronTriggerRelatedFlatEntityMaps > | undefined > { @@ -119,6 +134,7 @@ export class WorkspaceMigrationV2CronTriggerActionsBuilderService extends Worksp this.flatCronTriggerValidatorService.validateFlatCronTriggerUpdate({ flatCronTriggerToValidate: toFlatCronTrigger, optimisticFlatCronTriggerMaps, + dependencyOptimisticFlatEntityMaps, }); if (validationResult.errors.length > 0) { diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/types/database-event-trigger-related-flat-entity-maps.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/types/database-event-trigger-related-flat-entity-maps.type.ts new file mode 100644 index 00000000000..c29c2306db2 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/types/database-event-trigger-related-flat-entity-maps.type.ts @@ -0,0 +1,6 @@ +import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type'; + +export type DatabaseEventTriggerRelatedFlatEntityMaps = Pick< + AllFlatEntityMaps, + 'flatServerlessFunctionMaps' +>; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service.ts index e93270ed0bd..cd1eccd069d 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service.ts @@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common'; import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; import { compareTwoFlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/utils/compare-two-flat-database-event-trigger.util'; +import { DatabaseEventTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/types/database-event-trigger-related-flat-entity-maps.type'; import { FlatEntityUpdateValidationArgs, FlatEntityValidationArgs, @@ -19,7 +20,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten 'databaseEventTrigger', FlatDatabaseEventTrigger, WorkspaceMigrationDatabaseEventTriggerActionV2, - undefined + DatabaseEventTriggerRelatedFlatEntityMaps > { constructor( private readonly flatDatabaseEventTriggerValidatorService: FlatDatabaseEventTriggerValidatorService, @@ -31,10 +32,14 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten flatEntityToValidate: flatDatabaseEventTriggerToValidate, optimisticFlatEntityMaps: optimisticFlatDatabaseEventTriggerMaps, dependencyOptimisticFlatEntityMaps, - }: FlatEntityValidationArgs): Promise< + }: FlatEntityValidationArgs< + FlatDatabaseEventTrigger, + DatabaseEventTriggerRelatedFlatEntityMaps + >): Promise< FlatEntityValidationReturnType< WorkspaceMigrationDatabaseEventTriggerActionV2, - FlatDatabaseEventTrigger + FlatDatabaseEventTrigger, + DatabaseEventTriggerRelatedFlatEntityMaps > > { const validationResult = @@ -42,6 +47,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten { flatDatabaseEventTriggerToValidate, optimisticFlatDatabaseEventTriggerMaps, + dependencyOptimisticFlatEntityMaps, }, ); @@ -66,10 +72,14 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten flatEntityToValidate: flatDatabaseEventTriggerToValidate, optimisticFlatEntityMaps: optimisticFlatDatabaseEventTriggerMaps, dependencyOptimisticFlatEntityMaps, - }: FlatEntityValidationArgs): Promise< + }: FlatEntityValidationArgs< + FlatDatabaseEventTrigger, + DatabaseEventTriggerRelatedFlatEntityMaps + >): Promise< FlatEntityValidationReturnType< WorkspaceMigrationDatabaseEventTriggerActionV2, - FlatDatabaseEventTrigger + FlatDatabaseEventTrigger, + DatabaseEventTriggerRelatedFlatEntityMaps > > { const validationResult = @@ -77,6 +87,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten { flatDatabaseEventTriggerToValidate, optimisticFlatDatabaseEventTriggerMaps, + dependencyOptimisticFlatEntityMaps, }, ); @@ -104,10 +115,14 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten }, optimisticFlatEntityMaps: optimisticFlatDatabaseEventTriggerMaps, dependencyOptimisticFlatEntityMaps, - }: FlatEntityUpdateValidationArgs): Promise< + }: FlatEntityUpdateValidationArgs< + FlatDatabaseEventTrigger, + DatabaseEventTriggerRelatedFlatEntityMaps + >): Promise< | FlatEntityValidationReturnType< WorkspaceMigrationDatabaseEventTriggerActionV2, - FlatDatabaseEventTrigger + FlatDatabaseEventTrigger, + DatabaseEventTriggerRelatedFlatEntityMaps > | undefined > { @@ -126,6 +141,7 @@ export class WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService exten { flatDatabaseEventTriggerToValidate: toFlatDatabaseEventTrigger, optimisticFlatDatabaseEventTriggerMaps, + dependencyOptimisticFlatEntityMaps, }, ); diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/types/route-trigger-related-flat-entity-maps.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/types/route-trigger-related-flat-entity-maps.type.ts new file mode 100644 index 00000000000..7da54c29f6d --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/types/route-trigger-related-flat-entity-maps.type.ts @@ -0,0 +1,6 @@ +import { type AllFlatEntityMaps } from 'src/engine/core-modules/common/types/all-flat-entity-maps.type'; + +export type RouteTriggerRelatedFlatEntityMaps = Pick< + AllFlatEntityMaps, + 'flatServerlessFunctionMaps' +>; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service.ts new file mode 100644 index 00000000000..641a3e2920b --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service.ts @@ -0,0 +1,159 @@ +import { Injectable } from '@nestjs/common'; + +import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; +import { compareTwoFlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/utils/compare-two-flat-route-trigger.util'; +import { RouteTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/types/route-trigger-related-flat-entity-maps.type'; +import { + FlatEntityUpdateValidationArgs, + FlatEntityValidationArgs, + FlatEntityValidationReturnType, + WorkspaceEntityMigrationBuilderV2Service, +} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/services/workspace-entity-migration-builder-v2.service'; +import { + UpdateRouteTriggerAction, + WorkspaceMigrationRouteTriggerActionV2, +} from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type'; +import { FlatRouteTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service'; + +@Injectable() +export class WorkspaceMigrationV2RouteTriggerActionsBuilderService extends WorkspaceEntityMigrationBuilderV2Service< + 'routeTrigger', + FlatRouteTrigger, + WorkspaceMigrationRouteTriggerActionV2, + RouteTriggerRelatedFlatEntityMaps +> { + constructor( + private readonly flatRouteTriggerValidatorService: FlatRouteTriggerValidatorService, + ) { + super('routeTrigger'); + } + + protected async validateFlatEntityCreation({ + flatEntityToValidate: flatRouteTriggerToValidate, + optimisticFlatEntityMaps: optimisticFlatRouteTriggerMaps, + dependencyOptimisticFlatEntityMaps, + }: FlatEntityValidationArgs< + FlatRouteTrigger, + RouteTriggerRelatedFlatEntityMaps + >): Promise< + FlatEntityValidationReturnType< + WorkspaceMigrationRouteTriggerActionV2, + FlatRouteTrigger, + RouteTriggerRelatedFlatEntityMaps + > + > { + const validationResult = + await this.flatRouteTriggerValidatorService.validateFlatRouteTriggerCreation( + { + flatRouteTriggerToValidate, + optimisticFlatRouteTriggerMaps, + dependencyOptimisticFlatEntityMaps, + }, + ); + + if (validationResult.errors.length > 0) { + return { + status: 'fail', + ...validationResult, + }; + } + + return { + status: 'success', + action: { + type: 'create_route_trigger', + routeTrigger: flatRouteTriggerToValidate, + }, + dependencyOptimisticFlatEntityMaps, + }; + } + + protected async validateFlatEntityDeletion({ + flatEntityToValidate: flatRouteTriggerToValidate, + optimisticFlatEntityMaps: optimisticFlatRouteTriggerMaps, + dependencyOptimisticFlatEntityMaps, + }: FlatEntityValidationArgs< + FlatRouteTrigger, + RouteTriggerRelatedFlatEntityMaps + >): Promise< + FlatEntityValidationReturnType< + WorkspaceMigrationRouteTriggerActionV2, + FlatRouteTrigger, + RouteTriggerRelatedFlatEntityMaps + > + > { + const validationResult = + this.flatRouteTriggerValidatorService.validateFlatRouteTriggerDeletion({ + flatRouteTriggerToValidate, + optimisticFlatRouteTriggerMaps, + dependencyOptimisticFlatEntityMaps, + }); + + if (validationResult.errors.length > 0) { + return { + status: 'fail', + ...validationResult, + }; + } + + return { + status: 'success', + action: { + type: 'delete_route_trigger', + routeTriggerId: flatRouteTriggerToValidate.id, + }, + dependencyOptimisticFlatEntityMaps, + }; + } + + protected async validateFlatEntityUpdate({ + flatEntityUpdate: { from: fromFlatRouteTrigger, to: toFlatRouteTrigger }, + optimisticFlatEntityMaps: optimisticFlatRouteTriggerMaps, + dependencyOptimisticFlatEntityMaps, + }: FlatEntityUpdateValidationArgs< + FlatRouteTrigger, + RouteTriggerRelatedFlatEntityMaps + >): Promise< + | FlatEntityValidationReturnType< + WorkspaceMigrationRouteTriggerActionV2, + FlatRouteTrigger, + RouteTriggerRelatedFlatEntityMaps + > + | undefined + > { + const routeTriggerUpdatedProperties = compareTwoFlatRouteTrigger({ + fromFlatRouteTrigger, + toFlatRouteTrigger, + }); + + if (routeTriggerUpdatedProperties.length === 0) { + return undefined; + } + + const validationResult = + this.flatRouteTriggerValidatorService.validateFlatRouteTriggerUpdate({ + flatRouteTriggerToValidate: toFlatRouteTrigger, + optimisticFlatRouteTriggerMaps, + dependencyOptimisticFlatEntityMaps, + }); + + if (validationResult.errors.length > 0) { + return { + status: 'fail', + ...validationResult, + }; + } + + const updateRouteTriggerAction: UpdateRouteTriggerAction = { + type: 'update_route_trigger', + routeTriggerId: toFlatRouteTrigger.id, + updates: routeTriggerUpdatedProperties, + }; + + return { + status: 'success', + action: updateRouteTriggerAction, + dependencyOptimisticFlatEntityMaps, + }; + } +} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/view-field-related-flat-entity-maps.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/types/view-field-related-flat-entity-maps.type.ts similarity index 100% rename from packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/view-field-related-flat-entity-maps.type.ts rename to packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/types/view-field-related-flat-entity-maps.type.ts diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service.ts index e2f13f1fac7..d550a505b1f 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service.ts @@ -7,7 +7,7 @@ import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/core-modules/comm import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/core-modules/common/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util'; import { FlatViewField } from 'src/engine/core-modules/view/flat-view/types/flat-view-field.type'; import { compareTwoFlatViewField } from 'src/engine/core-modules/view/flat-view/utils/compare-two-flat-view-field.util'; -import { ViewFieldRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/view-field-related-flat-entity-maps.type'; +import { ViewFieldRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/types/view-field-related-flat-entity-maps.type'; import { FlatEntityUpdateValidationArgs, FlatEntityValidationArgs, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-action-common-v2.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-action-common-v2.ts index 31197057a77..96df25af220 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-action-common-v2.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-action-common-v2.ts @@ -3,6 +3,7 @@ import { type WorkspaceMigrationDatabaseEventTriggerActionV2 } from 'src/engine/ import { type WorkspaceMigrationFieldActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-field-action-v2'; import { type WorkspaceMigrationIndexActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-index-action-v2'; import { type WorkspaceMigrationObjectActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-object-action-v2'; +import { type WorkspaceMigrationRouteTriggerActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type'; import { type WorkspaceMigrationServerlessFunctionActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-serverless-function-action-v2.type'; import { type WorkspaceMigrationViewActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-action-v2.type'; import { type WorkspaceMigrationViewFieldActionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-view-field-action-v2.type'; @@ -15,7 +16,8 @@ export type WorkspaceMigrationActionV2 = | WorkspaceMigrationViewFieldActionV2 | WorkspaceMigrationServerlessFunctionActionV2 | WorkspaceMigrationDatabaseEventTriggerActionV2 - | WorkspaceMigrationCronTriggerActionV2; + | WorkspaceMigrationCronTriggerActionV2 + | WorkspaceMigrationRouteTriggerActionV2; export type WorkspaceMigrationActionTypeV2 = WorkspaceMigrationActionV2['type']; export type ExtractAction = Extract< diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type.ts new file mode 100644 index 00000000000..5c6f47ff9b7 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type.ts @@ -0,0 +1,31 @@ +import { type FlatRouteTriggerPropertiesToCompare } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger-properties-to-compare.type'; +import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; +import { type PropertyUpdate } from 'src/engine/workspace-manager/workspace-migration-v2/types/property-update.type'; + +export type CreateRouteTriggerAction = { + type: 'create_route_trigger'; + routeTrigger: FlatRouteTrigger; +}; + +export type UpdateRouteTriggerAction = { + type: 'update_route_trigger'; + routeTriggerId: string; + updates: Array< + { + [P in FlatRouteTriggerPropertiesToCompare]: PropertyUpdate< + FlatRouteTrigger, + P + >; + }[FlatRouteTriggerPropertiesToCompare] + >; +}; + +export type DeleteRouteTriggerAction = { + type: 'delete_route_trigger'; + routeTriggerId: string; +}; + +export type WorkspaceMigrationRouteTriggerActionV2 = + | CreateRouteTriggerAction + | UpdateRouteTriggerAction + | DeleteRouteTriggerAction; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-cron-trigger-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-cron-trigger-validator.service.ts index 54347889245..cb9f1d8893d 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-cron-trigger-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-cron-trigger-validator.service.ts @@ -6,11 +6,13 @@ import { isDefined } from 'twenty-shared/utils'; import { FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type'; import { CronTriggerExceptionCode } from 'src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception'; import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; +import { CronTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/types/cron-trigger-related-flat-entity-maps.type'; import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type'; type CronTriggerValidationArgs = { flatCronTriggerToValidate: FlatCronTrigger; optimisticFlatCronTriggerMaps: FlatEntityMaps; + dependencyOptimisticFlatEntityMaps: CronTriggerRelatedFlatEntityMaps; }; // TODO: validate settings integrity @Injectable() @@ -20,6 +22,7 @@ export class FlatCronTriggerValidatorService { public validateFlatCronTriggerUpdate({ flatCronTriggerToValidate: updatedFlatCronTrigger, optimisticFlatCronTriggerMaps, + dependencyOptimisticFlatEntityMaps, }: CronTriggerValidationArgs): FailedFlatEntityValidation { const errors = []; @@ -34,6 +37,19 @@ export class FlatCronTriggerValidatorService { }); } + const serverlessFunction = + dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[ + updatedFlatCronTrigger.serverlessFunctionId + ]; + + if (!isDefined(serverlessFunction)) { + errors.push({ + code: CronTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, + message: t`Serverless function not found`, + userFriendlyMessage: t`Serverless function not found`, + }); + } + return { type: 'update_cron_trigger', errors, @@ -72,6 +88,7 @@ export class FlatCronTriggerValidatorService { public async validateFlatCronTriggerCreation({ flatCronTriggerToValidate, optimisticFlatCronTriggerMaps, + dependencyOptimisticFlatEntityMaps, }: CronTriggerValidationArgs): Promise< FailedFlatEntityValidation > { @@ -89,6 +106,19 @@ export class FlatCronTriggerValidatorService { }); } + const serverlessFunction = + dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[ + flatCronTriggerToValidate.serverlessFunctionId + ]; + + if (!isDefined(serverlessFunction)) { + errors.push({ + code: CronTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, + message: t`Serverless function not found`, + userFriendlyMessage: t`Serverless function not found`, + }); + } + return { type: 'create_cron_trigger', errors, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-database-event-trigger-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-database-event-trigger-validator.service.ts index 11ffc9943eb..7da013a6de6 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-database-event-trigger-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-database-event-trigger-validator.service.ts @@ -6,11 +6,13 @@ import { isDefined } from 'twenty-shared/utils'; import { FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type'; import { DatabaseEventTriggerExceptionCode } from 'src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception'; import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; +import { DatabaseEventTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/types/database-event-trigger-related-flat-entity-maps.type'; import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type'; type DatabaseEventTriggerValidationArgs = { flatDatabaseEventTriggerToValidate: FlatDatabaseEventTrigger; optimisticFlatDatabaseEventTriggerMaps: FlatEntityMaps; + dependencyOptimisticFlatEntityMaps: DatabaseEventTriggerRelatedFlatEntityMaps; }; // TODO: validate settings integrity @Injectable() @@ -20,6 +22,7 @@ export class FlatDatabaseEventTriggerValidatorService { public validateFlatDatabaseEventTriggerUpdate({ flatDatabaseEventTriggerToValidate: updatedFlatDatabaseEventTrigger, optimisticFlatDatabaseEventTriggerMaps, + dependencyOptimisticFlatEntityMaps, }: DatabaseEventTriggerValidationArgs): FailedFlatEntityValidation { const errors = []; @@ -36,6 +39,19 @@ export class FlatDatabaseEventTriggerValidatorService { }); } + const serverlessFunction = + dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[ + updatedFlatDatabaseEventTrigger.serverlessFunctionId + ]; + + if (!isDefined(serverlessFunction)) { + errors.push({ + code: DatabaseEventTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, + message: t`Serverless function not found`, + userFriendlyMessage: t`Serverless function not found`, + }); + } + return { type: 'update_database_event_trigger', errors, @@ -76,6 +92,7 @@ export class FlatDatabaseEventTriggerValidatorService { public async validateFlatDatabaseEventTriggerCreation({ flatDatabaseEventTriggerToValidate, optimisticFlatDatabaseEventTriggerMaps, + dependencyOptimisticFlatEntityMaps, }: DatabaseEventTriggerValidationArgs): Promise< FailedFlatEntityValidation > { @@ -95,6 +112,19 @@ export class FlatDatabaseEventTriggerValidatorService { }); } + const serverlessFunction = + dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps?.byId?.[ + flatDatabaseEventTriggerToValidate.serverlessFunctionId + ]; + + if (!isDefined(serverlessFunction)) { + errors.push({ + code: DatabaseEventTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, + message: t`Serverless function not found`, + userFriendlyMessage: t`Serverless function not found`, + }); + } + return { type: 'create_database_event_trigger', errors, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service.ts new file mode 100644 index 00000000000..c83a19bb4e7 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service.ts @@ -0,0 +1,147 @@ +import { Injectable } from '@nestjs/common'; + +import { t } from '@lingui/core/macro'; +import { isDefined } from 'twenty-shared/utils'; + +import { FlatEntityMaps } from 'src/engine/core-modules/common/types/flat-entity-maps.type'; +import { RouteTriggerExceptionCode } from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception'; +import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; +import { RouteTriggerRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/types/route-trigger-related-flat-entity-maps.type'; +import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type'; + +type RouteTriggerValidationArgs = { + flatRouteTriggerToValidate: FlatRouteTrigger; + optimisticFlatRouteTriggerMaps: FlatEntityMaps; + dependencyOptimisticFlatEntityMaps: RouteTriggerRelatedFlatEntityMaps; +}; + +@Injectable() +export class FlatRouteTriggerValidatorService { + constructor() {} + + public validateFlatRouteTriggerUpdate({ + flatRouteTriggerToValidate: updatedFlatRouteTrigger, + optimisticFlatRouteTriggerMaps, + dependencyOptimisticFlatEntityMaps, + }: RouteTriggerValidationArgs): FailedFlatEntityValidation { + const errors = []; + + const existingFlatRouteTrigger = + optimisticFlatRouteTriggerMaps.byId[updatedFlatRouteTrigger.id]; + + if (!isDefined(existingFlatRouteTrigger)) { + errors.push({ + code: RouteTriggerExceptionCode.ROUTE_NOT_FOUND, + message: t`Route not found`, + userFriendlyMessage: t`Route not found`, + }); + } + + const serverlessFunction = + dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps.byId[ + updatedFlatRouteTrigger.serverlessFunctionId + ]; + + if (!isDefined(serverlessFunction)) { + errors.push({ + code: RouteTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, + message: t`Serverless function not found`, + userFriendlyMessage: t`Serverless function not found`, + }); + } + + return { + type: 'update_route_trigger', + errors, + flatEntityMinimalInformation: { + id: updatedFlatRouteTrigger.id, + }, + }; + } + + public validateFlatRouteTriggerDeletion({ + flatRouteTriggerToValidate: { id: routeTriggerIdToDelete }, + optimisticFlatRouteTriggerMaps, + }: RouteTriggerValidationArgs): FailedFlatEntityValidation { + const errors = []; + + const existingFlatRouteTrigger = + optimisticFlatRouteTriggerMaps.byId[routeTriggerIdToDelete]; + + if (!isDefined(existingFlatRouteTrigger)) { + errors.push({ + code: RouteTriggerExceptionCode.ROUTE_NOT_FOUND, + message: t`Route not found`, + userFriendlyMessage: t`Route not found`, + }); + } + + return { + type: 'delete_route_trigger', + errors, + flatEntityMinimalInformation: { + id: routeTriggerIdToDelete, + }, + }; + } + + public async validateFlatRouteTriggerCreation({ + flatRouteTriggerToValidate, + optimisticFlatRouteTriggerMaps, + dependencyOptimisticFlatEntityMaps, + }: RouteTriggerValidationArgs): Promise< + FailedFlatEntityValidation + > { + const errors = []; + + if ( + isDefined( + optimisticFlatRouteTriggerMaps.byId[flatRouteTriggerToValidate.id], + ) + ) { + errors.push({ + code: RouteTriggerExceptionCode.ROUTE_ALREADY_EXIST, + message: t`Route with same id already exists`, + userFriendlyMessage: t`Route already exists`, + }); + } + + const existingFlatRouteTriggers = Object.values( + optimisticFlatRouteTriggerMaps.byId, + ).filter(isDefined); + + if ( + existingFlatRouteTriggers.find( + (flatRouteTrigger) => + flatRouteTrigger.path === flatRouteTriggerToValidate.path, + ) + ) { + errors.push({ + code: RouteTriggerExceptionCode.ROUTE_PATH_ALREADY_EXIST, + message: t`Route with same path already exists`, + userFriendlyMessage: t`Route path already exists`, + }); + } + + const serverlessFunction = + dependencyOptimisticFlatEntityMaps.flatServerlessFunctionMaps.byId[ + flatRouteTriggerToValidate.serverlessFunctionId + ]; + + if (!isDefined(serverlessFunction)) { + errors.push({ + code: RouteTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, + message: t`Serverless function not found`, + userFriendlyMessage: t`Serverless function not found`, + }); + } + + return { + type: 'create_route_trigger', + errors, + flatEntityMinimalInformation: { + id: flatRouteTriggerToValidate.id, + }, + }; + } +} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service.ts index ee20bec4d49..15fce382f8b 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service.ts @@ -8,7 +8,7 @@ import { ViewExceptionCode } from 'src/engine/core-modules/view/exceptions/view. import { FlatViewFieldMaps } from 'src/engine/core-modules/view/flat-view/types/flat-view-field-maps.type'; import { FlatViewField } from 'src/engine/core-modules/view/flat-view/types/flat-view-field.type'; import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type'; -import { ViewFieldRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/view-field-related-flat-entity-maps.type'; +import { ViewFieldRelatedFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/types/view-field-related-flat-entity-maps.type'; type ViewFieldValidationArgs = { flatViewFieldToValidate: FlatViewField; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/workspace-migration-builder-validators.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/workspace-migration-builder-validators.module.ts index 92868fde0ab..14f624fed1a 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/workspace-migration-builder-validators.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/workspace-migration-builder-validators.module.ts @@ -1,12 +1,13 @@ import { Module } from '@nestjs/common'; -import { FlatFieldMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-field-metadata-validator.service'; -import { FlatObjectMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-object-metadata-validator.service'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { FlatFieldMetadataTypeValidatorService } from 'src/engine/metadata-modules/flat-field-metadata/services/flat-field-metadata-type-validator.service'; import { FlatCronTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-cron-trigger-validator.service'; import { FlatDatabaseEventTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-database-event-trigger-validator.service'; +import { FlatFieldMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-field-metadata-validator.service'; import { FlatIndexValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-index-metadata-validator.service'; +import { FlatObjectMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-object-metadata-validator.service'; +import { FlatRouteTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-route-trigger-validator.service'; import { FlatServerlessFunctionValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-serverless-function-validator.service'; import { FlatViewFieldValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-field-validator.service'; import { FlatViewValidatorService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/services/flat-view-validator.service'; @@ -23,6 +24,7 @@ import { FlatViewValidatorService } from 'src/engine/workspace-manager/workspace FlatDatabaseEventTriggerValidatorService, FlatCronTriggerValidatorService, FlatFieldMetadataTypeValidatorService, + FlatRouteTriggerValidatorService, ], exports: [ FlatViewValidatorService, @@ -34,6 +36,7 @@ import { FlatViewValidatorService } from 'src/engine/workspace-manager/workspace FlatDatabaseEventTriggerValidatorService, FlatCronTriggerValidatorService, FlatFieldMetadataTypeValidatorService, + FlatRouteTriggerValidatorService, ], }) export class WorkspaceMigrationBuilderValidatorsModule {} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-builder-v2.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-builder-v2.module.ts index c210c7cde56..5dc5fa54735 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-builder-v2.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-builder-v2.module.ts @@ -7,6 +7,7 @@ import { WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService } from 's import { WorkspaceMigrationV2FieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/services/workspace-migration-v2-field-actions-builder.service'; import { WorkspaceMigrationV2IndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service'; import { WorkspaceMigrationV2ObjectActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/services/workspace-migration-v2-object-actions-builder.service'; +import { WorkspaceMigrationV2RouteTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service'; import { WorkspaceMigrationV2ServerlessFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/workspace-migration-v2-serverless-function-actions-builder.service'; import { WorkspaceMigrationV2ViewFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service'; import { WorkspaceMigrationV2ViewActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/workspace-migration-v2-view-actions-builder.service'; @@ -24,6 +25,7 @@ import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace- WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService, WorkspaceMigrationV2FieldActionsBuilderService, WorkspaceMigrationV2CronTriggerActionsBuilderService, + WorkspaceMigrationV2RouteTriggerActionsBuilderService, ], exports: [ WorkspaceMigrationV2ViewActionsBuilderService, @@ -34,6 +36,8 @@ import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace- WorkspaceMigrationV2ServerlessFunctionActionsBuilderService, WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService, WorkspaceMigrationV2CronTriggerActionsBuilderService, + WorkspaceMigrationV2RouteTriggerActionsBuilderService, + FlatFieldMetadataTypeValidatorService, ], }) export class WorkspaceMigrationBuilderV2Module {} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/create-route-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/create-route-trigger-action-handler.service.ts new file mode 100644 index 00000000000..fa5fc16f12a --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/create-route-trigger-action-handler.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@nestjs/common'; + +import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface'; + +import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { CreateRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type'; +import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type'; + +@Injectable() +export class CreateRouteTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( + 'create_route_trigger', +) { + constructor() { + super(); + } + + async executeForMetadata( + context: WorkspaceMigrationActionRunnerArgs, + ): Promise { + const { action, queryRunner, workspaceId } = context; + const { routeTrigger } = action; + + const routeTriggerRepository = + queryRunner.manager.getRepository(RouteTrigger); + + await routeTriggerRepository.insert({ + ...routeTrigger, + workspaceId, + }); + } +} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service.ts new file mode 100644 index 00000000000..b2d04a9e159 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service.ts @@ -0,0 +1,31 @@ +import { Injectable } from '@nestjs/common'; + +import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface'; + +import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { DeleteRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type'; +import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type'; + +@Injectable() +export class DeleteRouteTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( + 'delete_route_trigger', +) { + constructor() { + super(); + } + + async executeForMetadata( + context: WorkspaceMigrationActionRunnerArgs, + ): Promise { + const { action, queryRunner, workspaceId } = context; + const { routeTriggerId } = action; + + const routeTriggerRepository = + queryRunner.manager.getRepository(RouteTrigger); + + await routeTriggerRepository.delete({ + id: routeTriggerId, + workspaceId, + }); + } +} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/update-route-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/update-route-trigger-action-handler.service.ts new file mode 100644 index 00000000000..fae8ae95861 --- /dev/null +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/update-route-trigger-action-handler.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@nestjs/common'; + +import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/interfaces/workspace-migration-runner-action-handler-service.interface'; + +import { RouteTrigger } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; +import { UpdateRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-route-trigger-action-v2.type'; +import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/types/workspace-migration-action-runner-args.type'; +import { fromWorkspaceMigrationUpdateActionToPartialEntity } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/utils/from-workspace-migration-update-action-to-partial-field-or-object-entity.util'; + +@Injectable() +export class UpdateRouteTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( + 'update_route_trigger', +) { + constructor() { + super(); + } + + async executeForMetadata( + context: WorkspaceMigrationActionRunnerArgs, + ): Promise { + const { action, queryRunner } = context; + const { routeTriggerId } = action; + + const routeTriggerRepository = + queryRunner.manager.getRepository(RouteTrigger); + + await routeTriggerRepository.update( + routeTriggerId, + fromWorkspaceMigrationUpdateActionToPartialEntity(action), + ); + } +} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts index 2f66809c7ac..f30d33deefc 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts @@ -15,6 +15,9 @@ import { DeleteIndexActionHandlerService } from 'src/engine/workspace-manager/wo import { CreateObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/object/services/create-object-action-handler.service'; import { DeleteObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/object/services/delete-object-action-handler.service'; import { UpdateObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/object/services/update-object-action-handler.service'; +import { CreateRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/create-route-trigger-action-handler.service'; +import { DeleteRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service'; +import { UpdateRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/update-route-trigger-action-handler.service'; import { CreateServerlessFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/create-serverless-function-action-handler.service'; import { DeleteServerlessFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/delete-serverless-function-action-handler.service'; import { UpdateServerlessFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/update-serverless-function-action-handler.service'; @@ -58,6 +61,10 @@ import { UpdateViewActionHandlerService } from 'src/engine/workspace-manager/wor CreateCronTriggerActionHandlerService, DeleteCronTriggerActionHandlerService, UpdateCronTriggerActionHandlerService, + + CreateRouteTriggerActionHandlerService, + DeleteRouteTriggerActionHandlerService, + UpdateRouteTriggerActionHandlerService, ], }) export class WorkspaceSchemaMigrationRunnerActionHandlersModule {} diff --git a/packages/twenty-server/test/integration/graphql/suites/view/__snapshots__/failing-create-view-field-v2.integration-spec.ts.snap b/packages/twenty-server/test/integration/graphql/suites/view/__snapshots__/failing-create-view-field-v2.integration-spec.ts.snap index 473f0c7377f..cf929eb4e83 100644 --- a/packages/twenty-server/test/integration/graphql/suites/view/__snapshots__/failing-create-view-field-v2.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/graphql/suites/view/__snapshots__/failing-create-view-field-v2.integration-spec.ts.snap @@ -10,6 +10,7 @@ exports[`View Field Resolver - Failing Create Operation - v2 should fail to crea "fieldMetadata": [], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [ @@ -38,6 +39,7 @@ exports[`View Field Resolver - Failing Create Operation - v2 should fail to crea "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -60,6 +62,7 @@ exports[`View Field Resolver - Failing Create Operation - v2 should fail to crea "fieldMetadata": [], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [ @@ -88,6 +91,7 @@ exports[`View Field Resolver - Failing Create Operation - v2 should fail to crea "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, diff --git a/packages/twenty-server/test/integration/metadata/suites/field-metadata/__snapshots__/create-one-field-metadata.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/field-metadata/__snapshots__/create-one-field-metadata.integration-spec.ts.snap index 56dc989f82f..30fdb2e1d3f 100644 --- a/packages/twenty-server/test/integration/metadata/suites/field-metadata/__snapshots__/create-one-field-metadata.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/field-metadata/__snapshots__/create-one-field-metadata.integration-spec.ts.snap @@ -28,6 +28,7 @@ exports[`createOne FieldMetadataService name/label sync should return an error w ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -39,6 +40,7 @@ exports[`createOne FieldMetadataService name/label sync should return an error w "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, diff --git a/packages/twenty-server/test/integration/metadata/suites/field-metadata/__snapshots__/update-one-field-metadata.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/field-metadata/__snapshots__/update-one-field-metadata.integration-spec.ts.snap index 3635b0c5522..c183049e28a 100644 --- a/packages/twenty-server/test/integration/metadata/suites/field-metadata/__snapshots__/update-one-field-metadata.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/field-metadata/__snapshots__/update-one-field-metadata.integration-spec.ts.snap @@ -28,6 +28,7 @@ exports[`updateOne failing update should not update a field name if it is not sy ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -39,6 +40,7 @@ exports[`updateOne failing update should not update a field name if it is not sy "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -86,6 +88,7 @@ exports[`updateOne failing update should throw if the field name is not availabl ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -97,6 +100,7 @@ exports[`updateOne failing update should throw if the field name is not availabl "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, diff --git a/packages/twenty-server/test/integration/metadata/suites/field-metadata/enum/__snapshots__/failing-create-one-field-metadata-enum-v2.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/field-metadata/enum/__snapshots__/failing-create-one-field-metadata-enum-v2.integration-spec.ts.snap index 6420d69dafb..e43814b19d9 100644 --- a/packages/twenty-server/test/integration/metadata/suites/field-metadata/enum/__snapshots__/failing-create-one-field-metadata-enum-v2.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/field-metadata/enum/__snapshots__/failing-create-one-field-metadata-enum-v2.integration-spec.ts.snap @@ -29,6 +29,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -40,6 +41,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -82,6 +84,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -93,6 +96,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -134,6 +138,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -145,6 +150,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -201,6 +207,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -212,6 +219,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -268,6 +276,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -279,6 +288,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -335,6 +345,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -346,6 +357,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -402,6 +414,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -413,6 +426,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -454,6 +468,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -465,6 +480,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -507,6 +523,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -518,6 +535,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -564,6 +582,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -575,6 +594,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -616,6 +636,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -627,6 +648,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -669,6 +691,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -680,6 +703,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -721,6 +745,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -732,6 +757,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -788,6 +814,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -799,6 +826,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -840,6 +868,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -851,6 +880,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -892,6 +922,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -903,6 +934,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -945,6 +977,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -956,6 +989,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -998,6 +1032,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1009,6 +1044,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1050,6 +1086,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1061,6 +1098,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1103,6 +1141,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1114,6 +1153,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1155,6 +1195,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1166,6 +1207,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1212,6 +1254,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1223,6 +1266,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1264,6 +1308,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1275,6 +1320,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1317,6 +1363,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1328,6 +1375,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1369,6 +1417,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1380,6 +1429,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1426,6 +1476,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1437,6 +1488,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1478,6 +1530,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1489,6 +1542,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1531,6 +1585,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1542,6 +1597,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1583,6 +1639,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1594,6 +1651,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1640,6 +1698,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1651,6 +1710,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1692,6 +1752,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1703,6 +1764,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1744,6 +1806,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1755,6 +1818,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1801,6 +1865,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1812,6 +1877,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1853,6 +1919,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1864,6 +1931,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1905,6 +1973,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1916,6 +1985,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1958,6 +2028,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1969,6 +2040,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2010,6 +2082,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2021,6 +2094,7 @@ exports[`Failing create field metadata MULTI_SELECT tests suite v2 Create should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2067,6 +2141,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2078,6 +2153,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2119,6 +2195,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2130,6 +2207,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2171,6 +2249,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2182,6 +2261,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2238,6 +2318,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2249,6 +2330,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2305,6 +2387,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2316,6 +2399,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2372,6 +2456,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2383,6 +2468,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2439,6 +2525,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2450,6 +2537,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2492,6 +2580,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2503,6 +2592,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2549,6 +2639,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2560,6 +2651,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2601,6 +2693,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2612,6 +2705,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2654,6 +2748,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2665,6 +2760,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2706,6 +2802,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2717,6 +2814,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2758,6 +2856,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2769,6 +2868,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2810,6 +2910,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2821,6 +2922,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2863,6 +2965,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2874,6 +2977,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2915,6 +3019,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2926,6 +3031,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2968,6 +3074,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2979,6 +3086,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3020,6 +3128,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3031,6 +3140,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3077,6 +3187,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3088,6 +3199,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3129,6 +3241,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3140,6 +3253,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3182,6 +3296,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3193,6 +3308,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3234,6 +3350,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3245,6 +3362,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3291,6 +3409,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3302,6 +3421,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3343,6 +3463,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3354,6 +3475,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3396,6 +3518,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3407,6 +3530,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3448,6 +3572,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3459,6 +3584,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3505,6 +3631,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3516,6 +3643,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3557,6 +3685,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3568,6 +3697,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3609,6 +3739,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3620,6 +3751,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3666,6 +3798,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3677,6 +3810,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3718,6 +3852,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3729,6 +3864,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3770,6 +3906,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3781,6 +3918,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3823,6 +3961,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3834,6 +3973,7 @@ exports[`Failing create field metadata SELECT tests suite v2 Create should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, diff --git a/packages/twenty-server/test/integration/metadata/suites/field-metadata/enum/__snapshots__/failing-update-one-enum-field-metadata-v2.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/field-metadata/enum/__snapshots__/failing-update-one-enum-field-metadata-v2.integration-spec.ts.snap index cd9d607a97d..d4eb844a58b 100644 --- a/packages/twenty-server/test/integration/metadata/suites/field-metadata/enum/__snapshots__/failing-update-one-enum-field-metadata-v2.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/field-metadata/enum/__snapshots__/failing-update-one-enum-field-metadata-v2.integration-spec.ts.snap @@ -29,6 +29,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -40,6 +41,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -82,6 +84,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -93,6 +96,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -134,6 +138,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -145,6 +150,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -201,6 +207,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -212,6 +219,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -268,6 +276,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -279,6 +288,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -335,6 +345,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -346,6 +357,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -402,6 +414,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -413,6 +426,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -454,6 +468,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -465,6 +480,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -507,6 +523,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -518,6 +535,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -564,6 +582,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -575,6 +594,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -616,6 +636,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -627,6 +648,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -669,6 +691,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -680,6 +703,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -721,6 +745,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -732,6 +757,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -788,6 +814,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -799,6 +826,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -840,6 +868,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -851,6 +880,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -892,6 +922,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -903,6 +934,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -945,6 +977,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -956,6 +989,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -998,6 +1032,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1009,6 +1044,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1050,6 +1086,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1061,6 +1098,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1103,6 +1141,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1114,6 +1153,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1155,6 +1195,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1166,6 +1207,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1212,6 +1254,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1223,6 +1266,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1264,6 +1308,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1275,6 +1320,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1316,6 +1362,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1327,6 +1374,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1373,6 +1421,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1384,6 +1433,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1425,6 +1475,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1436,6 +1487,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1478,6 +1530,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1489,6 +1542,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1530,6 +1584,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1541,6 +1596,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1587,6 +1643,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1598,6 +1655,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1639,6 +1697,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1650,6 +1709,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1691,6 +1751,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1702,6 +1763,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1748,6 +1810,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1759,6 +1822,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1800,6 +1864,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1811,6 +1876,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1852,6 +1918,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1863,6 +1930,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1904,6 +1972,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1915,6 +1984,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1956,6 +2026,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1967,6 +2038,7 @@ exports[`Failing update field metadata MULTI_SELECT tests suite v2 Update should "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2013,6 +2085,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2024,6 +2097,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2065,6 +2139,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2076,6 +2151,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2117,6 +2193,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2128,6 +2205,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2184,6 +2262,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2195,6 +2274,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2251,6 +2331,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2262,6 +2343,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2318,6 +2400,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2329,6 +2412,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2385,6 +2469,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2396,6 +2481,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2438,6 +2524,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2449,6 +2536,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2495,6 +2583,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2506,6 +2595,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2547,6 +2637,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2558,6 +2649,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2600,6 +2692,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2611,6 +2704,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2652,6 +2746,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2663,6 +2758,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2704,6 +2800,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2715,6 +2812,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2756,6 +2854,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2767,6 +2866,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2809,6 +2909,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2820,6 +2921,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2861,6 +2963,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2872,6 +2975,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2914,6 +3018,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2925,6 +3030,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2966,6 +3072,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -2977,6 +3084,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3023,6 +3131,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3034,6 +3143,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3075,6 +3185,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3086,6 +3197,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3127,6 +3239,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3138,6 +3251,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3184,6 +3298,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3195,6 +3310,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3236,6 +3352,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3247,6 +3364,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3289,6 +3407,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3300,6 +3419,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3341,6 +3461,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3352,6 +3473,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3398,6 +3520,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3409,6 +3532,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3450,6 +3574,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3461,6 +3586,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3502,6 +3628,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3513,6 +3640,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3559,6 +3687,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3570,6 +3699,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3611,6 +3741,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3622,6 +3753,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3663,6 +3795,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3674,6 +3807,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3715,6 +3849,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -3726,6 +3861,7 @@ exports[`Failing update field metadata SELECT tests suite v2 Update should fail "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, diff --git a/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-create-one-field-metadata-morph-relation-v2.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-create-one-field-metadata-morph-relation-v2.integration-spec.ts.snap index b494b4c547c..88f83a5f657 100644 --- a/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-create-one-field-metadata-morph-relation-v2.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/field-metadata/morph-relation/__snapshots__/failing-create-one-field-metadata-morph-relation-v2.integration-spec.ts.snap @@ -76,6 +76,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 Morh re }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -87,6 +88,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 Morh re "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -127,6 +129,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 Morh re ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -138,6 +141,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 Morh re "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -172,6 +176,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -183,6 +188,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -217,6 +223,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -228,6 +235,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -290,6 +298,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -301,6 +310,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -357,6 +367,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -368,6 +379,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -424,6 +436,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -435,6 +448,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -497,6 +511,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -508,6 +523,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -550,6 +566,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -561,6 +578,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -603,6 +621,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -614,6 +633,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -655,6 +675,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -666,6 +687,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -700,6 +722,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -711,6 +734,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -745,6 +769,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -756,6 +781,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -790,6 +816,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -801,6 +828,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -838,6 +866,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -849,6 +878,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -884,6 +914,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -895,6 +926,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -929,6 +961,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -940,6 +973,7 @@ exports[`failing createOne FieldMetadataService morph relation fields v2 it shou "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, diff --git a/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-creation.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-creation.integration-spec.ts.snap index 175a9314674..789bab43bee 100644 --- a/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-creation.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-creation.integration-spec.ts.snap @@ -29,6 +29,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -40,6 +41,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -82,6 +84,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -93,6 +96,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -141,6 +145,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -152,6 +157,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -194,6 +200,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -205,6 +212,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -253,6 +261,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -264,6 +273,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -306,6 +316,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -317,6 +328,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -359,6 +371,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -370,6 +383,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -411,6 +425,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -422,6 +437,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -496,6 +512,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE when }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -507,6 +524,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE when "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -549,6 +567,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE when "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -560,6 +579,7 @@ exports[`Field metadata relation creation should fail relation MANY_TO_ONE when "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -618,6 +638,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -629,6 +650,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -687,6 +709,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -698,6 +721,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -762,6 +786,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -773,6 +798,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -831,6 +857,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -842,6 +869,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -906,6 +934,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -917,6 +946,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -959,6 +989,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -970,6 +1001,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1012,6 +1044,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1023,6 +1056,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1064,6 +1098,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1075,6 +1110,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY (rela "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1149,6 +1185,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY when }, ], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1160,6 +1197,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY when "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1202,6 +1240,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY when "type": "create_field", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -1213,6 +1252,7 @@ exports[`Field metadata relation creation should fail relation ONE_TO_MANY when "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, diff --git a/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-update.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-update.integration-spec.ts.snap index 0ac527832b7..65553b4cc3b 100644 --- a/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-update.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/field-metadata/relation/__snapshots__/failing-field-metadata-relation-update.integration-spec.ts.snap @@ -44,6 +44,7 @@ exports[`Field metadata relation update should fail relation when name is change ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -55,6 +56,7 @@ exports[`Field metadata relation update should fail relation when name is change "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -136,6 +138,7 @@ exports[`Field metadata relation update should fail relation when name is not in ], "index": [], "objectMetadata": [], + "routeTrigger": [], "serverlessFunction": [], "view": [], "viewField": [], @@ -147,6 +150,7 @@ exports[`Field metadata relation update should fail relation when name is not in "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, diff --git a/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata-v2.integration-spec.ts.snap b/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata-v2.integration-spec.ts.snap index fdfbeb8833e..13f100c0d60 100644 --- a/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata-v2.integration-spec.ts.snap +++ b/packages/twenty-server/test/integration/metadata/suites/object-metadata/__snapshots__/failing-create-one-object-metadata-v2.integration-spec.ts.snap @@ -337,6 +337,7 @@ exports[`Object metadata creation should fail v2 when labelPlural contains only "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -363,6 +364,7 @@ exports[`Object metadata creation should fail v2 when labelPlural contains only "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -712,6 +714,7 @@ exports[`Object metadata creation should fail v2 when labelPlural exceeds maximu "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -738,6 +741,7 @@ exports[`Object metadata creation should fail v2 when labelPlural exceeds maximu "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1087,6 +1091,7 @@ exports[`Object metadata creation should fail v2 when labelPlural is empty 1`] = "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -1113,6 +1118,7 @@ exports[`Object metadata creation should fail v2 when labelPlural is empty 1`] = "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1462,6 +1468,7 @@ exports[`Object metadata creation should fail v2 when labelSingular contains onl "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -1488,6 +1495,7 @@ exports[`Object metadata creation should fail v2 when labelSingular contains onl "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -1837,6 +1845,7 @@ exports[`Object metadata creation should fail v2 when labelSingular exceeds maxi "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -1863,6 +1872,7 @@ exports[`Object metadata creation should fail v2 when labelSingular exceeds maxi "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2212,6 +2222,7 @@ exports[`Object metadata creation should fail v2 when labelSingular is empty 1`] "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -2238,6 +2249,7 @@ exports[`Object metadata creation should fail v2 when labelSingular is empty 1`] "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2588,6 +2600,7 @@ exports[`Object metadata creation should fail v2 when labels are identical 1`] = "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -2614,6 +2627,7 @@ exports[`Object metadata creation should fail v2 when labels are identical 1`] = "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -2964,6 +2978,7 @@ exports[`Object metadata creation should fail v2 when labels with whitespaces re "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -2990,6 +3005,7 @@ exports[`Object metadata creation should fail v2 when labels with whitespaces re "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3369,6 +3385,7 @@ exports[`Object metadata creation should fail v2 when name exceeds maximum lengt "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -3395,6 +3412,7 @@ exports[`Object metadata creation should fail v2 when name exceeds maximum lengt "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -3744,6 +3762,7 @@ exports[`Object metadata creation should fail v2 when namePlural has invalid cha "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -3770,6 +3789,7 @@ exports[`Object metadata creation should fail v2 when namePlural has invalid cha "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -4119,6 +4139,7 @@ exports[`Object metadata creation should fail v2 when namePlural is a reserved k "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -4145,6 +4166,7 @@ exports[`Object metadata creation should fail v2 when namePlural is a reserved k "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -4499,6 +4521,7 @@ exports[`Object metadata creation should fail v2 when namePlural is an empty str "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -4525,6 +4548,7 @@ exports[`Object metadata creation should fail v2 when namePlural is an empty str "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -4879,6 +4903,7 @@ exports[`Object metadata creation should fail v2 when namePlural is not camelCas "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -4905,6 +4930,7 @@ exports[`Object metadata creation should fail v2 when namePlural is not camelCas "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -5319,6 +5345,7 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -5345,6 +5372,7 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -5759,6 +5787,7 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -5785,6 +5814,7 @@ exports[`Object metadata creation should fail v2 when nameSingular contains only "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -6164,6 +6194,7 @@ exports[`Object metadata creation should fail v2 when nameSingular has invalid c "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -6190,6 +6221,7 @@ exports[`Object metadata creation should fail v2 when nameSingular has invalid c "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -6569,6 +6601,7 @@ exports[`Object metadata creation should fail v2 when nameSingular is a reserved "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -6595,6 +6628,7 @@ exports[`Object metadata creation should fail v2 when nameSingular is a reserved "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -7009,6 +7043,7 @@ exports[`Object metadata creation should fail v2 when nameSingular is an empty s "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -7035,6 +7070,7 @@ exports[`Object metadata creation should fail v2 when nameSingular is an empty s "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -7449,6 +7485,7 @@ exports[`Object metadata creation should fail v2 when nameSingular is not camelC "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -7475,6 +7512,7 @@ exports[`Object metadata creation should fail v2 when nameSingular is not camelC "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -7825,6 +7863,7 @@ exports[`Object metadata creation should fail v2 when names are identical 1`] = "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -7851,6 +7890,7 @@ exports[`Object metadata creation should fail v2 when names are identical 1`] = "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0, @@ -8201,6 +8241,7 @@ exports[`Object metadata creation should fail v2 when names with whitespaces res "type": "create_object", }, ], + "routeTrigger": [], "serverlessFunction": [], "view": [ { @@ -8227,6 +8268,7 @@ exports[`Object metadata creation should fail v2 when names with whitespaces res "invalidFieldMetadata": 0, "invalidIndex": 0, "invalidObjectMetadata": 0, + "invalidRouteTrigger": 0, "invalidServerlessFunction": 0, "invalidView": 0, "invalidViewField": 0,