From a4499d21bb7fce4ca880635fccd3a22d6e31c00b Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Tue, 27 Jan 2026 20:54:09 +0100 Subject: [PATCH] Migrate cron, databaseEventTrigger, httpRoute triggers to serverless functions (#17488) ## Summary Migrates trigger entities (`CronTriggerEntity`, `DatabaseEventTriggerEntity`, `RouteTriggerEntity`) into `ServerlessFunctionEntity` by storing trigger settings as JSONB columns directly on the serverless function. This simplifies the architecture since these relationships were effectively one-to-one. ## Changes ### Schema Changes - Added three new nullable JSONB columns to `ServerlessFunctionEntity`: - `cronTriggerSettings` - stores cron pattern - `databaseEventTriggerSettings` - stores event name and updated fields filter - `httpRouteTriggerSettings` - stores path, HTTP method, auth requirements, and forwarded headers ### Core Logic Updates - `CronTriggerCronJob` - now queries `ServerlessFunctionEntity` directly instead of `CronTriggerEntity` - `CallDatabaseEventTriggerJobsJob` - now queries `ServerlessFunctionEntity` directly - `RouteTriggerService` - now queries `ServerlessFunctionEntity` directly - `ApplicationSyncService` - extracts trigger settings from manifest and writes to serverless function --- .../src/generated-metadata/graphql.ts | 224 +-------- .../twenty-front/src/generated/graphql.ts | 185 +------- .../SettingsServerlessFunctionTriggersTab.tsx | 68 ++- .../fragments/serverlessFunctionFragment.ts | 21 - ...ete-orphaned-workspace-entities.command.ts | 6 - ...4-migrateServerlessTriggersToServerless.ts | 82 ++++ .../application/application-sync.module.ts | 6 - .../application/application-sync.service.ts | 444 ++---------------- ...on-trigger-editable-properties.constant.ts | 5 - .../cron-trigger/cron-trigger.module.ts | 29 +- .../crons/jobs/cron-trigger.cron.job.ts | 35 +- .../dtos/create-cron-trigger.input.ts | 25 - .../dtos/cron-trigger-id.input.ts | 11 - .../cron-trigger/dtos/cron-trigger.dto.ts | 28 -- .../dtos/update-cron-trigger.input.ts | 32 -- .../entities/cron-trigger.entity.ts | 50 -- .../exceptions/cron-trigger.exception.ts | 39 -- .../resolvers/cron-trigger.resolver.ts | 145 ------ .../services/cron-trigger-v2.service.ts | 193 -------- ...ace-flat-cron-trigger-map-cache.service.ts | 59 --- ...cron-trigger-properties-to-compare.type.ts | 6 - .../types/flat-cron-trigger.type.ts | 4 - ...gger-graphql-api-exception-handler.util.ts | 23 - ...ger-graphql-api-exception-handler.utils.ts | 9 - ...trigger-input-to-flat-cron-trigger.util.ts | 28 -- ...t-cron-trigger-to-cron-trigger-dto.util.ts | 11 - ...at-cron-trigger-to-update-or-throw.util.ts | 31 -- ...nt-trigger-editable-properties.constant.ts | 5 - .../database-event-trigger.module.ts | 27 +- .../create-database-event-trigger.input.ts | 25 - .../dtos/database-event-trigger-id.input.ts | 11 - .../dtos/database-event-trigger.dto.ts | 28 -- .../update-database-event-trigger.input.ts | 32 -- .../entities/database-event-trigger.entity.ts | 53 --- .../database-event-trigger.exception.ts | 43 -- .../call-database-event-trigger-jobs.job.ts | 29 +- .../database-event-trigger.resolver.ts | 150 ------ .../database-event-trigger-v2.service.ts | 202 -------- ...atabase-event-trigger-map-cache.service.ts | 60 --- .../types/flat-database-event-trigger.type.ts | 5 - ...form-event-batch-to-event-payloads.spec.ts | 131 +++--- ...ger-graphql-api-exception-handler.utils.ts | 25 - ...put-to-flat-database-event-trigger.util.ts | 29 -- ...gger-to-database-event-trigger-dto.util.ts | 11 - ...e-event-trigger-to-update-or-throw.util.ts | 32 -- ...transform-event-batch-to-event-payloads.ts | 15 +- ...rties-to-compare-and-stringify.constant.ts | 13 +- ...tadata-entity-by-metadata-name.constant.ts | 9 +- .../all-metadata-relations.constant.ts | 30 +- .../all-flat-entity-types-by-metadata-name.ts | 48 +- ...a-related-metadata-names.util.spec.ts.snap | 28 +- ...ata-names-children-first.util.spec.ts.snap | 10 +- .../metadata-engine.module.ts | 4 - ...te-trigger-editable-properties.constant.ts | 8 - .../dtos/create-route-trigger.input.ts | 51 -- .../dtos/route-trigger-id.input.ts | 11 - .../route-trigger/dtos/route-trigger.dto.ts | 32 -- .../dtos/update-route-trigger.input.ts | 59 --- .../resolvers/route-trigger.resolver.ts | 149 ------ .../route-trigger/route-trigger.entity.ts | 66 --- .../route-trigger/route-trigger.module.ts | 24 +- .../route-trigger/route-trigger.service.ts | 66 +-- .../services/route-trigger-v2.service.ts | 192 -------- ...ce-flat-route-trigger-map-cache.service.ts | 60 --- .../types/flat-route-trigger.type.ts | 4 - ...rigger-input-to-flat-route-trigger.util.ts | 33 -- ...route-trigger-to-route-trigger-dto.util.ts | 14 - ...t-route-trigger-to-update-or-throw.util.ts | 36 -- ...ger-graphql-api-exception-handler.utils.ts | 23 - .../dtos/serverless-function.dto.ts | 26 +- .../serverless-function.entity.ts | 51 +- .../serverless-function.module.ts | 10 +- .../serverless-function.resolver.ts | 110 +---- ...t-serverless-function-map-cache.service.ts | 79 +--- ...-input-to-flat-serverless-function.util.ts | 6 +- ...unction-to-serverless-function-dto.util.ts | 39 +- ...entity-to-flat-serverless-function.util.ts | 14 +- ...ce-migration-build-orchestrator.service.ts | 118 ----- ...pace-migration-cron-trigger-action.type.ts | 12 - ...ion-cron-trigger-action-builder.service.ts | 111 ----- ...tion-database-event-trigger-action.type.ts | 12 - ...e-event-trigger-actions-builder.service.ts | 121 ----- ...ace-migration-route-trigger-action.type.ts | 12 - ...n-route-trigger-actions-builder.service.ts | 114 ----- .../flat-cron-trigger-validator.service.ts | 149 ------ ...atabase-event-trigger-validator.service.ts | 159 ------- .../flat-route-trigger-validator.service.ts | 166 ------- ...ace-migration-builder-validators.module.ts | 9 - .../workspace-migration-builder.module.ts | 9 - ...ate-cron-trigger-action-handler.service.ts | 32 -- ...ete-cron-trigger-action-handler.service.ts | 38 -- ...ate-cron-trigger-action-handler.service.ts | 33 -- ...se-event-trigger-action-handler.service.ts | 34 -- ...se-event-trigger-action-handler.service.ts | 42 -- ...se-event-trigger-action-handler.service.ts | 35 -- ...te-route-trigger-action-handler.service.ts | 32 -- ...te-route-trigger-action-handler.service.ts | 38 -- ...te-route-trigger-action-handler.service.ts | 33 -- ...migration-runner-action-handlers.module.ts | 21 - ...ate-action-on-all-flat-entity-maps.util.ts | 3 - ...ete-action-on-all-flat-entity-maps.util.ts | 3 - ...ate-action-on-all-flat-entity-maps.util.ts | 3 - ...-step-operations.workspace-service.spec.ts | 12 +- ...and-workspace-creation.integration-spec.ts | 50 +- ...ate-one-cron-trigger-query-factory.util.ts | 27 -- .../utils/create-one-cron-trigger.util.ts | 43 -- ...tabase-event-trigger-query-factory.util.ts | 28 -- .../create-one-database-event-trigger.util.ts | 44 -- ...te-one-route-trigger-query-factory.util.ts | 29 -- .../utils/create-one-route-trigger.util.ts | 43 -- 110 files changed, 439 insertions(+), 5193 deletions(-) create mode 100644 packages/twenty-server/src/database/typeorm/core/migrations/common/1769532887284-migrateServerlessTriggersToServerless.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/constants/flat-cron-trigger-editable-properties.constant.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/create-cron-trigger.input.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/cron-trigger-id.input.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/cron-trigger.dto.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/update-cron-trigger.input.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/resolvers/cron-trigger.resolver.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/workspace-flat-cron-trigger-map-cache.service.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger-properties-to-compare.type.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/cron-trigger-graphql-api-exception-handler.util.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/cron-trigger-graphql-api-exception-handler.utils.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-create-cron-trigger-input-to-flat-cron-trigger.util.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-flat-cron-trigger-to-cron-trigger-dto.util.ts delete mode 100644 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 delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/constants/flat-database-event-trigger-editable-properties.constant.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/create-database-event-trigger.input.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger-id.input.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger.dto.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/update-database-event-trigger.input.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/resolvers/database-event-trigger.resolver.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/workspace-flat-database-event-trigger-map-cache.service.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/database-event-trigger-graphql-api-exception-handler.utils.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-create-database-event-trigger-input-to-flat-database-event-trigger.util.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-flat-database-event-trigger-to-database-event-trigger-dto.util.ts delete mode 100644 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 delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-editable-properties.constant.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-create-route-trigger-input-to-flat-route-trigger.util.ts delete mode 100644 packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-flat-route-trigger-to-route-trigger-dto.util.ts delete 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 delete 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/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/types/workspace-migration-cron-trigger-action.type.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/workspace-migration-cron-trigger-action-builder.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/types/workspace-migration-database-event-trigger-action.type.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/workspace-migration-database-event-trigger-actions-builder.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/types/workspace-migration-route-trigger-action.type.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/workspace-migration-route-trigger-actions-builder.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-cron-trigger-validator.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-database-event-trigger-validator.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-route-trigger-validator.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/create-cron-trigger-action-handler.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/delete-cron-trigger-action-handler.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/update-cron-trigger-action-handler.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/create-database-event-trigger-action-handler.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/delete-database-event-trigger-action-handler.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/update-database-event-trigger-action-handler.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/create-route-trigger-action-handler.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service.ts delete mode 100644 packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/update-route-trigger-action-handler.service.ts delete mode 100644 packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-cron-trigger-query-factory.util.ts delete mode 100644 packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-cron-trigger.util.ts delete mode 100644 packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-database-event-trigger-query-factory.util.ts delete mode 100644 packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-database-event-trigger.util.ts delete mode 100644 packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-route-trigger-query-factory.util.ts delete mode 100644 packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-route-trigger.util.ts diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index e13dacdf9e..20b27a9f5c 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -932,16 +932,6 @@ export type CreateCommandMenuItemInput = { workflowVersionId: Scalars['UUID']; }; -export type CreateCronTriggerInput = { - serverlessFunctionId: Scalars['String']; - settings: Scalars['JSON']; -}; - -export type CreateDatabaseEventTriggerInput = { - serverlessFunctionId: Scalars['String']; - settings: Scalars['JSON']; -}; - export type CreateDraftFromWorkflowVersionInput = { /** Workflow ID */ workflowId: Scalars['UUID']; @@ -1053,15 +1043,6 @@ export type CreateRoleInput = { label: Scalars['String']; }; -export type CreateRouteTriggerInput = { - /** List of HTTP header names to forward to the serverless function event */ - forwardedRequestHeaders?: Array; - httpMethod?: HttpMethod; - isAuthRequired?: Scalars['Boolean']; - path: Scalars['String']; - serverlessFunctionId: Scalars['String']; -}; - export type CreateServerlessFunctionInput = { builtHandlerPath?: InputMaybe; code?: InputMaybe; @@ -1183,18 +1164,6 @@ export type CreateWorkflowVersionStepInput = { workflowVersionId: Scalars['UUID']; }; -export type CronTrigger = { - __typename?: 'CronTrigger'; - createdAt: Scalars['DateTime']; - id: Scalars['UUID']; - settings: Scalars['JSON']; - updatedAt: Scalars['DateTime']; -}; - -export type CronTriggerIdInput = { - id: Scalars['String']; -}; - export type CursorPaging = { /** Paginate after opaque cursor */ after?: InputMaybe; @@ -1216,18 +1185,6 @@ export enum DatabaseEventAction { UPSERTED = 'UPSERTED' } -export type DatabaseEventTrigger = { - __typename?: 'DatabaseEventTrigger'; - createdAt: Scalars['DateTime']; - id: Scalars['UUID']; - settings: Scalars['JSON']; - updatedAt: Scalars['DateTime']; -}; - -export type DatabaseEventTriggerIdInput = { - id: Scalars['String']; -}; - export type DateTimeFilter = { eq?: InputMaybe; gt?: InputMaybe; @@ -1715,14 +1672,6 @@ 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', @@ -2021,12 +1970,9 @@ export type Mutation = { createObjectEvent: Analytics; createOneAgent: Agent; createOneAppToken: AppToken; - createOneCronTrigger: CronTrigger; - createOneDatabaseEventTrigger: DatabaseEventTrigger; createOneField: Field; createOneObject: Object; createOneRole: Role; - createOneRouteTrigger: RouteTrigger; createOneServerlessFunction: ServerlessFunction; createOneServerlessFunctionLayer: ServerlessFunctionLayer; createPageLayout: PageLayout; @@ -2056,12 +2002,9 @@ export type Mutation = { deleteJobs: DeleteJobsResponse; deleteNavigationMenuItem: NavigationMenuItem; deleteOneAgent: Agent; - deleteOneCronTrigger: CronTrigger; - deleteOneDatabaseEventTrigger: DatabaseEventTrigger; deleteOneField: Field; deleteOneObject: Object; deleteOneRole: Scalars['String']; - deleteOneRouteTrigger: RouteTrigger; deleteOneServerlessFunction: ServerlessFunction; deletePublicDomain: Scalars['Boolean']; deleteSSOIdentityProvider: DeleteSsoOutput; @@ -2145,12 +2088,9 @@ export type Mutation = { updateNavigationMenuItem: NavigationMenuItem; updateOneAgent: Agent; updateOneApplicationVariable: Scalars['Boolean']; - updateOneCronTrigger: CronTrigger; - updateOneDatabaseEventTrigger: DatabaseEventTrigger; updateOneField: Field; updateOneObject: Object; updateOneRole: Role; - updateOneRouteTrigger: RouteTrigger; updateOneServerlessFunction: ServerlessFunction; updatePageLayout: PageLayout; updatePageLayoutTab: PageLayoutTab; @@ -2353,16 +2293,6 @@ export type MutationCreateOneAppTokenArgs = { }; -export type MutationCreateOneCronTriggerArgs = { - input: CreateCronTriggerInput; -}; - - -export type MutationCreateOneDatabaseEventTriggerArgs = { - input: CreateDatabaseEventTriggerInput; -}; - - export type MutationCreateOneFieldArgs = { input: CreateOneFieldMetadataInput; }; @@ -2378,11 +2308,6 @@ export type MutationCreateOneRoleArgs = { }; -export type MutationCreateOneRouteTriggerArgs = { - input: CreateRouteTriggerInput; -}; - - export type MutationCreateOneServerlessFunctionArgs = { input: CreateServerlessFunctionInput; }; @@ -2525,16 +2450,6 @@ export type MutationDeleteOneAgentArgs = { }; -export type MutationDeleteOneCronTriggerArgs = { - input: CronTriggerIdInput; -}; - - -export type MutationDeleteOneDatabaseEventTriggerArgs = { - input: DatabaseEventTriggerIdInput; -}; - - export type MutationDeleteOneFieldArgs = { input: DeleteOneFieldInput; }; @@ -2550,11 +2465,6 @@ export type MutationDeleteOneRoleArgs = { }; -export type MutationDeleteOneRouteTriggerArgs = { - input: RouteTriggerIdInput; -}; - - export type MutationDeleteOneServerlessFunctionArgs = { input: ServerlessFunctionIdInput; }; @@ -2960,16 +2870,6 @@ export type MutationUpdateOneApplicationVariableArgs = { }; -export type MutationUpdateOneCronTriggerArgs = { - input: UpdateCronTriggerInput; -}; - - -export type MutationUpdateOneDatabaseEventTriggerArgs = { - input: UpdateDatabaseEventTriggerInput; -}; - - export type MutationUpdateOneFieldArgs = { input: UpdateOneFieldMetadataInput; }; @@ -2985,11 +2885,6 @@ export type MutationUpdateOneRoleArgs = { }; -export type MutationUpdateOneRouteTriggerArgs = { - input: UpdateRouteTriggerInput; -}; - - export type MutationUpdateOneServerlessFunctionArgs = { input: UpdateServerlessFunctionInput; }; @@ -3583,16 +3478,10 @@ export type Query = { fields: FieldConnection; findManyAgents: Array; findManyApplications: Array; - findManyCronTriggers: Array; - findManyDatabaseEventTriggers: Array; findManyPublicDomains: Array; - findManyRouteTriggers: Array; findManyServerlessFunctions: Array; findOneAgent: Agent; findOneApplication: Application; - findOneCronTrigger: CronTrigger; - findOneDatabaseEventTrigger: DatabaseEventTrigger; - findOneRouteTrigger: RouteTrigger; findOneServerlessFunction: ServerlessFunction; findWorkspaceFromInviteHash: Workspace; findWorkspaceInvitations: Array; @@ -3728,21 +3617,6 @@ export type QueryFindOneApplicationArgs = { }; -export type QueryFindOneCronTriggerArgs = { - input: CronTriggerIdInput; -}; - - -export type QueryFindOneDatabaseEventTriggerArgs = { - input: DatabaseEventTriggerIdInput; -}; - - -export type QueryFindOneRouteTriggerArgs = { - input: RouteTriggerIdInput; -}; - - export type QueryFindOneServerlessFunctionArgs = { input: ServerlessFunctionIdInput; }; @@ -4158,22 +4032,6 @@ export type Role = { workspaceMembers: Array; }; -export type RouteTrigger = { - __typename?: 'RouteTrigger'; - createdAt: Scalars['DateTime']; - /** List of HTTP header names to forward to the serverless function event */ - forwardedRequestHeaders: Array; - httpMethod: HttpMethod; - id: Scalars['ID']; - isAuthRequired: Scalars['Boolean']; - path: Scalars['String']; - updatedAt: Scalars['DateTime']; -}; - -export type RouteTriggerIdInput = { - id: Scalars['String']; -}; - export type RowLevelPermissionPredicate = { __typename?: 'RowLevelPermissionPredicate'; fieldMetadataId: Scalars['String']; @@ -4330,16 +4188,16 @@ export type ServerlessFunction = { applicationId?: Maybe; builtHandlerPath: Scalars['String']; createdAt: Scalars['DateTime']; - cronTriggers?: Maybe>; - databaseEventTriggers?: Maybe>; + cronTriggerSettings?: Maybe; + databaseEventTriggerSettings?: Maybe; description?: Maybe; handlerName: Scalars['String']; + httpRouteTriggerSettings?: Maybe; id: Scalars['UUID']; isTool: Scalars['Boolean']; latestVersion?: Maybe; name: Scalars['String']; publishedVersions: Array; - routeTriggers?: Maybe>; runtime: Scalars['String']; sourceHandlerPath: Scalars['String']; timeoutSeconds: Scalars['Float']; @@ -4715,28 +4573,6 @@ export type UpdateCommandMenuItemInput = { label?: InputMaybe; }; -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']; -}; - export type UpdateFieldInput = { defaultValue?: InputMaybe; description?: InputMaybe; @@ -4874,21 +4710,6 @@ 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 = { - /** List of HTTP header names to forward to the serverless function event */ - forwardedRequestHeaders?: Array; - httpMethod: HttpMethod; - isAuthRequired: Scalars['Boolean']; - path: Scalars['String']; -}; - export type UpdateServerlessFunctionInput = { /** Id of the serverless function to update */ id: Scalars['UUID']; @@ -5738,7 +5559,7 @@ export type UpdateOneApplicationVariableMutationVariables = Exact<{ export type UpdateOneApplicationVariableMutation = { __typename?: 'Mutation', updateOneApplicationVariable: boolean }; -export type ApplicationFieldsFragment = { __typename?: 'Application', id: string, name: string, description: string, version: string, universalIdentifier: string, canBeUninstalled: boolean, applicationVariables: Array<{ __typename?: 'ApplicationVariable', id: string, key: string, value: string, description: string, isSecret: boolean }>, agents: Array<{ __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, prompt: string, modelId: string, responseFormat?: any | null, roleId?: string | null, isCustom: boolean, modelConfiguration?: any | null, evaluationInputs: Array, applicationId?: string | null, createdAt: string, updatedAt: string }>, objects: Array<{ __typename?: 'Object', id: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, isCustom: boolean, isRemote: boolean, isActive: boolean, isSystem: boolean, isUIReadOnly: boolean, createdAt: string, updatedAt: string, labelIdentifierFieldMetadataId?: string | null, imageIdentifierFieldMetadataId?: string | null, applicationId: string, shortcut?: string | null, isLabelSyncedWithName: boolean, isSearchable: boolean, duplicateCriteria?: Array> | null, indexMetadataList: Array<{ __typename?: 'Index', id: string, createdAt: string, updatedAt: string, name: string, indexWhereClause?: string | null, indexType: IndexType, isUnique: boolean, isCustom?: boolean | null, indexFieldMetadataList: Array<{ __typename?: 'IndexField', id: string, fieldMetadataId: string, createdAt: string, updatedAt: string, order: number }> }>, fieldsList: Array<{ __typename?: 'Field', id: string, type: FieldMetadataType, name: string, label: string, description?: string | null, icon?: string | null, isCustom?: boolean | null, isActive?: boolean | null, isSystem?: boolean | null, isUIReadOnly?: boolean | null, isNullable?: boolean | null, isUnique?: boolean | null, createdAt: string, updatedAt: string, defaultValue?: any | null, options?: any | null, settings?: any | null, isLabelSyncedWithName?: boolean | null, morphId?: string | null, applicationId: string, relation?: { __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } } | null, morphRelations?: Array<{ __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } }> | null }> }>, serverlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array, createdAt: string, updatedAt: string }> | null }> }; +export type ApplicationFieldsFragment = { __typename?: 'Application', id: string, name: string, description: string, version: string, universalIdentifier: string, canBeUninstalled: boolean, applicationVariables: Array<{ __typename?: 'ApplicationVariable', id: string, key: string, value: string, description: string, isSecret: boolean }>, agents: Array<{ __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, prompt: string, modelId: string, responseFormat?: any | null, roleId?: string | null, isCustom: boolean, modelConfiguration?: any | null, evaluationInputs: Array, applicationId?: string | null, createdAt: string, updatedAt: string }>, objects: Array<{ __typename?: 'Object', id: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, isCustom: boolean, isRemote: boolean, isActive: boolean, isSystem: boolean, isUIReadOnly: boolean, createdAt: string, updatedAt: string, labelIdentifierFieldMetadataId?: string | null, imageIdentifierFieldMetadataId?: string | null, applicationId: string, shortcut?: string | null, isLabelSyncedWithName: boolean, isSearchable: boolean, duplicateCriteria?: Array> | null, indexMetadataList: Array<{ __typename?: 'Index', id: string, createdAt: string, updatedAt: string, name: string, indexWhereClause?: string | null, indexType: IndexType, isUnique: boolean, isCustom?: boolean | null, indexFieldMetadataList: Array<{ __typename?: 'IndexField', id: string, fieldMetadataId: string, createdAt: string, updatedAt: string, order: number }> }>, fieldsList: Array<{ __typename?: 'Field', id: string, type: FieldMetadataType, name: string, label: string, description?: string | null, icon?: string | null, isCustom?: boolean | null, isActive?: boolean | null, isSystem?: boolean | null, isUIReadOnly?: boolean | null, isNullable?: boolean | null, isUnique?: boolean | null, createdAt: string, updatedAt: string, defaultValue?: any | null, options?: any | null, settings?: any | null, isLabelSyncedWithName?: boolean | null, morphId?: string | null, applicationId: string, relation?: { __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } } | null, morphRelations?: Array<{ __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } }> | null }> }>, serverlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string }> }; export type FindManyApplicationsQueryVariables = Exact<{ [key: string]: never; }>; @@ -5750,7 +5571,7 @@ export type FindOneApplicationQueryVariables = Exact<{ }>; -export type FindOneApplicationQuery = { __typename?: 'Query', findOneApplication: { __typename?: 'Application', id: string, name: string, description: string, version: string, universalIdentifier: string, canBeUninstalled: boolean, applicationVariables: Array<{ __typename?: 'ApplicationVariable', id: string, key: string, value: string, description: string, isSecret: boolean }>, agents: Array<{ __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, prompt: string, modelId: string, responseFormat?: any | null, roleId?: string | null, isCustom: boolean, modelConfiguration?: any | null, evaluationInputs: Array, applicationId?: string | null, createdAt: string, updatedAt: string }>, objects: Array<{ __typename?: 'Object', id: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, isCustom: boolean, isRemote: boolean, isActive: boolean, isSystem: boolean, isUIReadOnly: boolean, createdAt: string, updatedAt: string, labelIdentifierFieldMetadataId?: string | null, imageIdentifierFieldMetadataId?: string | null, applicationId: string, shortcut?: string | null, isLabelSyncedWithName: boolean, isSearchable: boolean, duplicateCriteria?: Array> | null, indexMetadataList: Array<{ __typename?: 'Index', id: string, createdAt: string, updatedAt: string, name: string, indexWhereClause?: string | null, indexType: IndexType, isUnique: boolean, isCustom?: boolean | null, indexFieldMetadataList: Array<{ __typename?: 'IndexField', id: string, fieldMetadataId: string, createdAt: string, updatedAt: string, order: number }> }>, fieldsList: Array<{ __typename?: 'Field', id: string, type: FieldMetadataType, name: string, label: string, description?: string | null, icon?: string | null, isCustom?: boolean | null, isActive?: boolean | null, isSystem?: boolean | null, isUIReadOnly?: boolean | null, isNullable?: boolean | null, isUnique?: boolean | null, createdAt: string, updatedAt: string, defaultValue?: any | null, options?: any | null, settings?: any | null, isLabelSyncedWithName?: boolean | null, morphId?: string | null, applicationId: string, relation?: { __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } } | null, morphRelations?: Array<{ __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } }> | null }> }>, serverlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array, createdAt: string, updatedAt: string }> | null }> } }; +export type FindOneApplicationQuery = { __typename?: 'Query', findOneApplication: { __typename?: 'Application', id: string, name: string, description: string, version: string, universalIdentifier: string, canBeUninstalled: boolean, applicationVariables: Array<{ __typename?: 'ApplicationVariable', id: string, key: string, value: string, description: string, isSecret: boolean }>, agents: Array<{ __typename?: 'Agent', id: string, name: string, label: string, description?: string | null, icon?: string | null, prompt: string, modelId: string, responseFormat?: any | null, roleId?: string | null, isCustom: boolean, modelConfiguration?: any | null, evaluationInputs: Array, applicationId?: string | null, createdAt: string, updatedAt: string }>, objects: Array<{ __typename?: 'Object', id: string, nameSingular: string, namePlural: string, labelSingular: string, labelPlural: string, description?: string | null, icon?: string | null, isCustom: boolean, isRemote: boolean, isActive: boolean, isSystem: boolean, isUIReadOnly: boolean, createdAt: string, updatedAt: string, labelIdentifierFieldMetadataId?: string | null, imageIdentifierFieldMetadataId?: string | null, applicationId: string, shortcut?: string | null, isLabelSyncedWithName: boolean, isSearchable: boolean, duplicateCriteria?: Array> | null, indexMetadataList: Array<{ __typename?: 'Index', id: string, createdAt: string, updatedAt: string, name: string, indexWhereClause?: string | null, indexType: IndexType, isUnique: boolean, isCustom?: boolean | null, indexFieldMetadataList: Array<{ __typename?: 'IndexField', id: string, fieldMetadataId: string, createdAt: string, updatedAt: string, order: number }> }>, fieldsList: Array<{ __typename?: 'Field', id: string, type: FieldMetadataType, name: string, label: string, description?: string | null, icon?: string | null, isCustom?: boolean | null, isActive?: boolean | null, isSystem?: boolean | null, isUIReadOnly?: boolean | null, isNullable?: boolean | null, isUnique?: boolean | null, createdAt: string, updatedAt: string, defaultValue?: any | null, options?: any | null, settings?: any | null, isLabelSyncedWithName?: boolean | null, morphId?: string | null, applicationId: string, relation?: { __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } } | null, morphRelations?: Array<{ __typename?: 'Relation', type: RelationType, sourceObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, targetObjectMetadata: { __typename?: 'Object', id: string, nameSingular: string, namePlural: string }, sourceFieldMetadata: { __typename?: 'Field', id: string, name: string }, targetFieldMetadata: { __typename?: 'Field', id: string, name: string } }> | null }> }>, serverlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string }> } }; export type UploadFileMutationVariables = Exact<{ file: Scalars['Upload']; @@ -6607,21 +6428,21 @@ export type GetSsoIdentityProvidersQueryVariables = Exact<{ [key: string]: never export type GetSsoIdentityProvidersQuery = { __typename?: 'Query', getSSOIdentityProviders: Array<{ __typename?: 'FindAvailableSSOIDPOutput', type: IdentityProviderType, id: string, name: string, issuer: string, status: SsoIdentityProviderStatus }> }; -export type ServerlessFunctionFieldsFragment = { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array, createdAt: string, updatedAt: string }> | null }; +export type ServerlessFunctionFieldsFragment = { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string }; export type CreateOneServerlessFunctionItemMutationVariables = Exact<{ input: CreateServerlessFunctionInput; }>; -export type CreateOneServerlessFunctionItemMutation = { __typename?: 'Mutation', createOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array, createdAt: string, updatedAt: string }> | null } }; +export type CreateOneServerlessFunctionItemMutation = { __typename?: 'Mutation', createOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string } }; export type DeleteOneServerlessFunctionMutationVariables = Exact<{ input: ServerlessFunctionIdInput; }>; -export type DeleteOneServerlessFunctionMutation = { __typename?: 'Mutation', deleteOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array, createdAt: string, updatedAt: string }> | null } }; +export type DeleteOneServerlessFunctionMutation = { __typename?: 'Mutation', deleteOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string } }; export type ExecuteOneServerlessFunctionMutationVariables = Exact<{ input: ExecuteServerlessFunctionInput; @@ -6635,14 +6456,14 @@ export type PublishOneServerlessFunctionMutationVariables = Exact<{ }>; -export type PublishOneServerlessFunctionMutation = { __typename?: 'Mutation', publishServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array, createdAt: string, updatedAt: string }> | null } }; +export type PublishOneServerlessFunctionMutation = { __typename?: 'Mutation', publishServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string } }; export type UpdateOneServerlessFunctionMutationVariables = Exact<{ input: UpdateServerlessFunctionInput; }>; -export type UpdateOneServerlessFunctionMutation = { __typename?: 'Mutation', updateOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array, createdAt: string, updatedAt: string }> | null } }; +export type UpdateOneServerlessFunctionMutation = { __typename?: 'Mutation', updateOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string } }; export type FindManyAvailablePackagesQueryVariables = Exact<{ input: ServerlessFunctionIdInput; @@ -6654,14 +6475,14 @@ export type FindManyAvailablePackagesQuery = { __typename?: 'Query', getAvailabl export type GetManyServerlessFunctionsQueryVariables = Exact<{ [key: string]: never; }>; -export type GetManyServerlessFunctionsQuery = { __typename?: 'Query', findManyServerlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array, createdAt: string, updatedAt: string }> | null }> }; +export type GetManyServerlessFunctionsQuery = { __typename?: 'Query', findManyServerlessFunctions: Array<{ __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string }> }; export type GetOneServerlessFunctionQueryVariables = Exact<{ input: ServerlessFunctionIdInput; }>; -export type GetOneServerlessFunctionQuery = { __typename?: 'Query', findOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string, cronTriggers?: Array<{ __typename?: 'CronTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, databaseEventTriggers?: Array<{ __typename?: 'DatabaseEventTrigger', id: string, settings: any, createdAt: string, updatedAt: string }> | null, routeTriggers?: Array<{ __typename?: 'RouteTrigger', id: string, path: string, isAuthRequired: boolean, httpMethod: HttpMethod, forwardedRequestHeaders: Array, createdAt: string, updatedAt: string }> | null } }; +export type GetOneServerlessFunctionQuery = { __typename?: 'Query', findOneServerlessFunction: { __typename?: 'ServerlessFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, latestVersion?: string | null, publishedVersions: Array, sourceHandlerPath: string, builtHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string } }; export type FindOneServerlessFunctionSourceCodeQueryVariables = Exact<{ input: GetServerlessFunctionSourceCodeInput; @@ -7330,27 +7151,6 @@ export const ServerlessFunctionFieldsFragmentDoc = gql` sourceHandlerPath builtHandlerPath handlerName - cronTriggers { - id - settings - createdAt - updatedAt - } - databaseEventTriggers { - id - settings - createdAt - updatedAt - } - routeTriggers { - id - path - isAuthRequired - httpMethod - forwardedRequestHeaders - createdAt - updatedAt - } toolInputSchema isTool applicationId diff --git a/packages/twenty-front/src/generated/graphql.ts b/packages/twenty-front/src/generated/graphql.ts index 344dab7e60..6235a7a187 100644 --- a/packages/twenty-front/src/generated/graphql.ts +++ b/packages/twenty-front/src/generated/graphql.ts @@ -928,16 +928,6 @@ export type CreateCommandMenuItemInput = { workflowVersionId: Scalars['UUID']; }; -export type CreateCronTriggerInput = { - serverlessFunctionId: Scalars['String']; - settings: Scalars['JSON']; -}; - -export type CreateDatabaseEventTriggerInput = { - serverlessFunctionId: Scalars['String']; - settings: Scalars['JSON']; -}; - export type CreateDraftFromWorkflowVersionInput = { /** Workflow ID */ workflowId: Scalars['UUID']; @@ -1029,15 +1019,6 @@ export type CreateRoleInput = { label: Scalars['String']; }; -export type CreateRouteTriggerInput = { - /** List of HTTP header names to forward to the serverless function event */ - forwardedRequestHeaders?: Array; - httpMethod?: HttpMethod; - isAuthRequired?: Scalars['Boolean']; - path: Scalars['String']; - serverlessFunctionId: Scalars['String']; -}; - export type CreateServerlessFunctionInput = { builtHandlerPath?: InputMaybe; code?: InputMaybe; @@ -1150,18 +1131,6 @@ export type CreateWorkflowVersionStepInput = { workflowVersionId: Scalars['UUID']; }; -export type CronTrigger = { - __typename?: 'CronTrigger'; - createdAt: Scalars['DateTime']; - id: Scalars['UUID']; - settings: Scalars['JSON']; - updatedAt: Scalars['DateTime']; -}; - -export type CronTriggerIdInput = { - id: Scalars['String']; -}; - export type CursorPaging = { /** Paginate after opaque cursor */ after?: InputMaybe; @@ -1183,18 +1152,6 @@ export enum DatabaseEventAction { UPSERTED = 'UPSERTED' } -export type DatabaseEventTrigger = { - __typename?: 'DatabaseEventTrigger'; - createdAt: Scalars['DateTime']; - id: Scalars['UUID']; - settings: Scalars['JSON']; - updatedAt: Scalars['DateTime']; -}; - -export type DatabaseEventTriggerIdInput = { - id: Scalars['String']; -}; - export type DateTimeFilter = { eq?: InputMaybe; gt?: InputMaybe; @@ -1682,14 +1639,6 @@ 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', @@ -1984,12 +1933,9 @@ export type Mutation = { createObjectEvent: Analytics; createOneAgent: Agent; createOneAppToken: AppToken; - createOneCronTrigger: CronTrigger; - createOneDatabaseEventTrigger: DatabaseEventTrigger; createOneField: Field; createOneObject: Object; createOneRole: Role; - createOneRouteTrigger: RouteTrigger; createOneServerlessFunction: ServerlessFunction; createOneServerlessFunctionLayer: ServerlessFunctionLayer; createPageLayout: PageLayout; @@ -2015,12 +1961,9 @@ export type Mutation = { deleteFile: File; deleteJobs: DeleteJobsResponse; deleteOneAgent: Agent; - deleteOneCronTrigger: CronTrigger; - deleteOneDatabaseEventTrigger: DatabaseEventTrigger; deleteOneField: Field; deleteOneObject: Object; deleteOneRole: Scalars['String']; - deleteOneRouteTrigger: RouteTrigger; deleteOneServerlessFunction: ServerlessFunction; deletePublicDomain: Scalars['Boolean']; deleteSSOIdentityProvider: DeleteSsoOutput; @@ -2099,12 +2042,9 @@ export type Mutation = { updateLabPublicFeatureFlag: FeatureFlagDto; updateOneAgent: Agent; updateOneApplicationVariable: Scalars['Boolean']; - updateOneCronTrigger: CronTrigger; - updateOneDatabaseEventTrigger: DatabaseEventTrigger; updateOneField: Field; updateOneObject: Object; updateOneRole: Role; - updateOneRouteTrigger: RouteTrigger; updateOneServerlessFunction: ServerlessFunction; updatePageLayout: PageLayout; updatePageLayoutTab: PageLayoutTab; @@ -2286,16 +2226,6 @@ export type MutationCreateOneAgentArgs = { }; -export type MutationCreateOneCronTriggerArgs = { - input: CreateCronTriggerInput; -}; - - -export type MutationCreateOneDatabaseEventTriggerArgs = { - input: CreateDatabaseEventTriggerInput; -}; - - export type MutationCreateOneFieldArgs = { input: CreateOneFieldMetadataInput; }; @@ -2311,11 +2241,6 @@ export type MutationCreateOneRoleArgs = { }; -export type MutationCreateOneRouteTriggerArgs = { - input: CreateRouteTriggerInput; -}; - - export type MutationCreateOneServerlessFunctionArgs = { input: CreateServerlessFunctionInput; }; @@ -2438,16 +2363,6 @@ export type MutationDeleteOneAgentArgs = { }; -export type MutationDeleteOneCronTriggerArgs = { - input: CronTriggerIdInput; -}; - - -export type MutationDeleteOneDatabaseEventTriggerArgs = { - input: DatabaseEventTriggerIdInput; -}; - - export type MutationDeleteOneFieldArgs = { input: DeleteOneFieldInput; }; @@ -2463,11 +2378,6 @@ export type MutationDeleteOneRoleArgs = { }; -export type MutationDeleteOneRouteTriggerArgs = { - input: RouteTriggerIdInput; -}; - - export type MutationDeleteOneServerlessFunctionArgs = { input: ServerlessFunctionIdInput; }; @@ -2847,16 +2757,6 @@ export type MutationUpdateOneApplicationVariableArgs = { }; -export type MutationUpdateOneCronTriggerArgs = { - input: UpdateCronTriggerInput; -}; - - -export type MutationUpdateOneDatabaseEventTriggerArgs = { - input: UpdateDatabaseEventTriggerInput; -}; - - export type MutationUpdateOneFieldArgs = { input: UpdateOneFieldMetadataInput; }; @@ -2872,11 +2772,6 @@ export type MutationUpdateOneRoleArgs = { }; -export type MutationUpdateOneRouteTriggerArgs = { - input: UpdateRouteTriggerInput; -}; - - export type MutationUpdateOneServerlessFunctionArgs = { input: UpdateServerlessFunctionInput; }; @@ -3461,16 +3356,10 @@ export type Query = { fields: FieldConnection; findManyAgents: Array; findManyApplications: Array; - findManyCronTriggers: Array; - findManyDatabaseEventTriggers: Array; findManyPublicDomains: Array; - findManyRouteTriggers: Array; findManyServerlessFunctions: Array; findOneAgent: Agent; findOneApplication: Application; - findOneCronTrigger: CronTrigger; - findOneDatabaseEventTrigger: DatabaseEventTrigger; - findOneRouteTrigger: RouteTrigger; findOneServerlessFunction: ServerlessFunction; findWorkspaceFromInviteHash: Workspace; findWorkspaceInvitations: Array; @@ -3573,21 +3462,6 @@ export type QueryFindOneApplicationArgs = { }; -export type QueryFindOneCronTriggerArgs = { - input: CronTriggerIdInput; -}; - - -export type QueryFindOneDatabaseEventTriggerArgs = { - input: DatabaseEventTriggerIdInput; -}; - - -export type QueryFindOneRouteTriggerArgs = { - input: RouteTriggerIdInput; -}; - - export type QueryFindOneServerlessFunctionArgs = { input: ServerlessFunctionIdInput; }; @@ -3961,22 +3835,6 @@ export type Role = { workspaceMembers: Array; }; -export type RouteTrigger = { - __typename?: 'RouteTrigger'; - createdAt: Scalars['DateTime']; - /** List of HTTP header names to forward to the serverless function event */ - forwardedRequestHeaders: Array; - httpMethod: HttpMethod; - id: Scalars['ID']; - isAuthRequired: Scalars['Boolean']; - path: Scalars['String']; - updatedAt: Scalars['DateTime']; -}; - -export type RouteTriggerIdInput = { - id: Scalars['String']; -}; - export type RowLevelPermissionPredicate = { __typename?: 'RowLevelPermissionPredicate'; fieldMetadataId: Scalars['String']; @@ -4133,16 +3991,16 @@ export type ServerlessFunction = { applicationId?: Maybe; builtHandlerPath: Scalars['String']; createdAt: Scalars['DateTime']; - cronTriggers?: Maybe>; - databaseEventTriggers?: Maybe>; + cronTriggerSettings?: Maybe; + databaseEventTriggerSettings?: Maybe; description?: Maybe; handlerName: Scalars['String']; + httpRouteTriggerSettings?: Maybe; id: Scalars['UUID']; isTool: Scalars['Boolean']; latestVersion?: Maybe; name: Scalars['String']; publishedVersions: Array; - routeTriggers?: Maybe>; runtime: Scalars['String']; sourceHandlerPath: Scalars['String']; timeoutSeconds: Scalars['Float']; @@ -4518,28 +4376,6 @@ export type UpdateCommandMenuItemInput = { label?: InputMaybe; }; -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']; -}; - export type UpdateFieldInput = { defaultValue?: InputMaybe; description?: InputMaybe; @@ -4653,21 +4489,6 @@ 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 = { - /** List of HTTP header names to forward to the serverless function event */ - forwardedRequestHeaders?: Array; - httpMethod: HttpMethod; - isAuthRequired: Scalars['Boolean']; - path: Scalars['String']; -}; - export type UpdateServerlessFunctionInput = { /** Id of the serverless function to update */ id: Scalars['UUID']; diff --git a/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTriggersTab.tsx b/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTriggersTab.tsx index a7806f5b11..b930f13810 100644 --- a/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTriggersTab.tsx +++ b/packages/twenty-front/src/modules/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTriggersTab.tsx @@ -1,27 +1,25 @@ import { FormTextFieldInput } from '@/object-record/record-field/ui/form-types/components/FormTextFieldInput'; import { SettingsDatabaseEventsForm } from '@/settings/components/SettingsDatabaseEventsForm'; import { Table } from '@/ui/layout/table/components/Table'; -import { TableCell } from '@/ui/layout/table/components/TableCell'; import { TableHeader } from '@/ui/layout/table/components/TableHeader'; import { TableRow } from '@/ui/layout/table/components/TableRow'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; -import { Tag } from 'twenty-ui/components'; -import { H2Title, OverflowingTextWithTooltip } from 'twenty-ui/display'; +import { H2Title } from 'twenty-ui/display'; import { Section } from 'twenty-ui/layout'; -import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { type ServerlessFunction } from '~/generated/graphql'; export const StyledRouteTriggerTableRow = styled(TableRow)` grid-template-columns: 1fr 120px 120px; `; -const StyledTableCell = styled(TableCell)` - color: ${({ theme }) => theme.font.color.tertiary}; - gap: ${({ theme }) => theme.spacing(2)}; - min-width: 0; - overflow: hidden; -`; +// TODO: @Charles put back with new sources +// const StyledTableCell = styled(TableCell)` +// color: ${({ theme }) => theme.font.color.tertiary}; +// gap: ${({ theme }) => theme.spacing(2)}; +// min-width: 0; +// overflow: hidden; +// `; const StyledRouteTriggerTableHeaderRow = styled(StyledRouteTriggerTableRow)` margin-bottom: ${({ theme }) => theme.spacing(2)}; @@ -38,24 +36,17 @@ const StyledEmptyState = styled.div` `; export const SettingsServerlessFunctionTriggersTab = ({ - serverlessFunction, + serverlessFunction: _serverlessFunction, }: { serverlessFunction: ServerlessFunction; }) => { const { t } = useLingui(); - const databaseEventTriggers = serverlessFunction.databaseEventTriggers ?? []; + const cronTriggers: [] = []; - const cronTriggers = serverlessFunction.cronTriggers ?? []; + const routeTriggers: [] = []; - const routeTriggers = serverlessFunction.routeTriggers ?? []; - - const databaseEvents = databaseEventTriggers?.map((event) => { - const [object, action]: [string, string] = - event.settings.eventName.split('.'); - - return { object, action, updatedFields: event.settings.updatedFields }; - }); + const databaseEvents: [] = []; const hasNoTriggers = databaseEvents.length === 0 && @@ -102,7 +93,7 @@ export const SettingsServerlessFunctionTriggersTab = ({ hint={t`Format: [Minute] [Hour] [Day of Month] [Month] [Day of Week]`} onChange={() => {}} readonly - defaultValue={cronTrigger.settings.pattern} + defaultValue={cronTrigger} /> ))} @@ -120,22 +111,23 @@ export const SettingsServerlessFunctionTriggersTab = ({ {t`Method`} {t`Auth Required`} - {routeTriggers.map((routeTrigger, index) => ( - - - - - {routeTrigger.httpMethod} - - - - + {routeTriggers.map((_, _index) => ( + <> + // + // + // + // + // {routeTrigger.httpMethod} + // + // + // + // ))} diff --git a/packages/twenty-front/src/modules/settings/serverless-functions/graphql/fragments/serverlessFunctionFragment.ts b/packages/twenty-front/src/modules/settings/serverless-functions/graphql/fragments/serverlessFunctionFragment.ts index 3855dbe294..21ac2adf1e 100644 --- a/packages/twenty-front/src/modules/settings/serverless-functions/graphql/fragments/serverlessFunctionFragment.ts +++ b/packages/twenty-front/src/modules/settings/serverless-functions/graphql/fragments/serverlessFunctionFragment.ts @@ -12,27 +12,6 @@ export const SERVERLESS_FUNCTION_FRAGMENT = gql` sourceHandlerPath builtHandlerPath handlerName - cronTriggers { - id - settings - createdAt - updatedAt - } - databaseEventTriggers { - id - settings - createdAt - updatedAt - } - routeTriggers { - id - path - isAuthRequired - httpMethod - forwardedRequestHeaders - createdAt - updatedAt - } toolInputSchema isTool applicationId diff --git a/packages/twenty-server/src/database/commands/list-and-delete-orphaned-workspace-entities.command.ts b/packages/twenty-server/src/database/commands/list-and-delete-orphaned-workspace-entities.command.ts index 4abeca2d61..cbe426b7c4 100644 --- a/packages/twenty-server/src/database/commands/list-and-delete-orphaned-workspace-entities.command.ts +++ b/packages/twenty-server/src/database/commands/list-and-delete-orphaned-workspace-entities.command.ts @@ -24,9 +24,7 @@ import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user import { WebhookEntity } from 'src/engine/metadata-modules/webhook/entities/webhook.entity'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity'; -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity'; -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; @@ -38,7 +36,6 @@ import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entiti import { PermissionFlagEntity } from 'src/engine/metadata-modules/permission-flag/permission-flag.entity'; import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity'; import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity'; -import { RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity'; import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity'; import { SearchFieldMetadataEntity } from 'src/engine/metadata-modules/search-field-metadata/search-field-metadata.entity'; @@ -81,9 +78,6 @@ const WORKSPACE_RELATED_ENTITIES: EntityTarget[] = [ ViewEntity, IndexMetadataEntity, PageLayoutTabEntity, - RouteTriggerEntity, - CronTriggerEntity, - DatabaseEventTriggerEntity, // Level 2: Children that depend on core entities FieldMetadataEntity, diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/common/1769532887284-migrateServerlessTriggersToServerless.ts b/packages/twenty-server/src/database/typeorm/core/migrations/common/1769532887284-migrateServerlessTriggersToServerless.ts new file mode 100644 index 0000000000..3f1a6b85fc --- /dev/null +++ b/packages/twenty-server/src/database/typeorm/core/migrations/common/1769532887284-migrateServerlessTriggersToServerless.ts @@ -0,0 +1,82 @@ +import { type MigrationInterface, type QueryRunner } from 'typeorm'; + +export class MigrateServerlessTriggersToServerless1769532887284 + implements MigrationInterface +{ + name = 'MigrateServerlessTriggersToServerless1769532887284'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."serverlessFunction" ADD "cronTriggerSettings" jsonb`, + ); + await queryRunner.query( + `ALTER TABLE "core"."serverlessFunction" ADD "databaseEventTriggerSettings" jsonb`, + ); + await queryRunner.query( + `ALTER TABLE "core"."serverlessFunction" ADD "httpRouteTriggerSettings" jsonb`, + ); + await queryRunner.query( + `DROP TABLE IF EXISTS "core"."cronTrigger" CASCADE`, + ); + await queryRunner.query( + `DROP TABLE IF EXISTS "core"."databaseEventTrigger" CASCADE`, + ); + await queryRunner.query( + `DROP TABLE IF EXISTS "core"."routeTrigger" CASCADE`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."serverlessFunction" DROP COLUMN "httpRouteTriggerSettings"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."serverlessFunction" DROP COLUMN "databaseEventTriggerSettings"`, + ); + await queryRunner.query( + `ALTER TABLE "core"."serverlessFunction" DROP COLUMN "cronTriggerSettings"`, + ); + await queryRunner.query(` + CREATE TABLE "core"."cronTrigger" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "settings" jsonb NOT NULL, + "serverlessFunctionId" uuid NOT NULL, + "workspaceId" uuid NOT NULL, + "universalIdentifier" uuid NOT NULL, + "applicationId" uuid NOT NULL, + "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + CONSTRAINT "PK_cronTrigger" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "core"."databaseEventTrigger" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "settings" jsonb NOT NULL, + "serverlessFunctionId" uuid NOT NULL, + "workspaceId" uuid NOT NULL, + "universalIdentifier" uuid NOT NULL, + "applicationId" uuid NOT NULL, + "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + CONSTRAINT "PK_databaseEventTrigger" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + CREATE TABLE "core"."routeTrigger" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "path" character varying NOT NULL, + "isAuthRequired" boolean NOT NULL DEFAULT true, + "httpMethod" character varying NOT NULL DEFAULT 'GET', + "forwardedRequestHeaders" jsonb NOT NULL DEFAULT '[]', + "serverlessFunctionId" uuid NOT NULL, + "workspaceId" uuid NOT NULL, + "universalIdentifier" uuid NOT NULL, + "applicationId" uuid NOT NULL, + "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + CONSTRAINT "PK_routeTrigger" PRIMARY KEY ("id") + ) + `); + } +} diff --git a/packages/twenty-server/src/engine/core-modules/application/application-sync.module.ts b/packages/twenty-server/src/engine/core-modules/application/application-sync.module.ts index 0b9c2927c8..fec50a51e6 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-sync.module.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-sync.module.ts @@ -7,9 +7,7 @@ import { ApplicationResolver } from 'src/engine/core-modules/application/applica import { ApplicationVariableEntityModule } from 'src/engine/core-modules/applicationVariable/application-variable.module'; import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module'; import { FileEntity } from 'src/engine/core-modules/file/entities/file.entity'; -import { CronTriggerModule } from 'src/engine/metadata-modules/cron-trigger/cron-trigger.module'; import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; -import { DatabaseEventTriggerModule } from 'src/engine/metadata-modules/database-event-trigger/database-event-trigger.module'; import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module'; import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module'; import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; @@ -17,7 +15,6 @@ import { ObjectPermissionModule } from 'src/engine/metadata-modules/object-permi import { PermissionFlagModule } from 'src/engine/metadata-modules/permission-flag/permission-flag.module'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; import { RoleModule } from 'src/engine/metadata-modules/role/role.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'; import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module'; import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module'; @@ -37,9 +34,6 @@ import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-commo DataSourceModule, ServerlessFunctionLayerModule, ServerlessFunctionModule, - DatabaseEventTriggerModule, - CronTriggerModule, - RouteTriggerModule, WorkspaceMigrationModule, PermissionsModule, RoleModule, 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 da6968b838..567b25047f 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 @@ -23,11 +23,7 @@ import { import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { ApplicationInput } from 'src/engine/core-modules/application/dtos/application.input'; import { ApplicationVariableEntityService } from 'src/engine/core-modules/applicationVariable/application-variable.service'; -import { CronTriggerV2Service } from 'src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service'; -import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; -import { DatabaseEventTriggerV2Service } from 'src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service'; -import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input'; import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/services/field-metadata.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; @@ -39,13 +35,16 @@ import { FieldPermissionService } from 'src/engine/metadata-modules/object-permi import { ObjectPermissionService } from 'src/engine/metadata-modules/object-permission/object-permission.service'; import { PermissionFlagService } from 'src/engine/metadata-modules/permission-flag/permission-flag.service'; import { RoleService } from 'src/engine/metadata-modules/role/role.service'; -import { RouteTriggerV2Service } from 'src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service'; -import { FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; import { ServerlessFunctionLayerService } from 'src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.service'; import { ServerlessFunctionV2Service } from 'src/engine/metadata-modules/serverless-function/services/serverless-function-v2.service'; import { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type'; import { computeMetadataNameFromLabelOrThrow } from 'src/engine/metadata-modules/utils/compute-metadata-name-from-label-or-throw.util'; import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service'; +import { + CronTriggerSettings, + DatabaseEventTriggerSettings, + HttpRouteTriggerSettings, +} from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; @Injectable() export class ApplicationSyncService { @@ -60,9 +59,6 @@ export class ApplicationSyncService { private readonly serverlessFunctionV2Service: ServerlessFunctionV2Service, private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService, private readonly dataSourceService: DataSourceService, - private readonly databaseEventTriggerV2Service: DatabaseEventTriggerV2Service, - private readonly cronTriggerV2Service: CronTriggerV2Service, - private readonly routeTriggerV2Service: RouteTriggerV2Service, private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, private readonly roleService: RoleService, private readonly objectPermissionService: ObjectPermissionService, @@ -960,26 +956,8 @@ export class ApplicationSyncService { workspaceId, ); - await this.syncDatabaseEventTriggersForServerlessFunction({ - serverlessFunctionId: serverlessFunctionToUpdate.id, - triggersToSync: serverlessFunctionToSync.triggers || [], - workspaceId, - applicationId, - }); - - await this.syncCronTriggersForServerlessFunction({ - serverlessFunctionId: serverlessFunctionToUpdate.id, - triggersToSync: serverlessFunctionToSync.triggers || [], - workspaceId, - applicationId, - }); - - await this.syncRouteTriggersForServerlessFunction({ - serverlessFunctionId: serverlessFunctionToUpdate.id, - triggersToSync: serverlessFunctionToSync.triggers || [], - workspaceId, - applicationId, - }); + // Trigger settings are now embedded in the serverless function entity + // They are handled through the update input } for (const serverlessFunctionToCreate of serverlessFunctionsToCreate) { @@ -1001,390 +979,52 @@ export class ApplicationSyncService { isTool: serverlessFunctionToCreate.isTool, }; - const createdServerlessFunction = - await this.serverlessFunctionV2Service.createOne({ - createServerlessFunctionInput, - workspaceId, - applicationId, - }); - - await this.syncDatabaseEventTriggersForServerlessFunction({ - serverlessFunctionId: createdServerlessFunction.id, - triggersToSync: serverlessFunctionToCreate.triggers || [], + await this.serverlessFunctionV2Service.createOne({ + createServerlessFunctionInput, workspaceId, applicationId, }); - await this.syncCronTriggersForServerlessFunction({ - serverlessFunctionId: createdServerlessFunction.id, - triggersToSync: serverlessFunctionToCreate.triggers || [], - workspaceId, - applicationId, - }); - - await this.syncRouteTriggersForServerlessFunction({ - serverlessFunctionId: createdServerlessFunction.id, - triggersToSync: serverlessFunctionToCreate.triggers || [], - workspaceId, - applicationId, - }); + // Trigger settings are now embedded in the serverless function entity + // They are handled through the create input } } - private async syncDatabaseEventTriggersForServerlessFunction({ - serverlessFunctionId, - triggersToSync, - workspaceId, - applicationId, - }: { - serverlessFunctionId: string; - triggersToSync: ServerlessFunctionTriggerManifest[]; - workspaceId: string; - applicationId: string; - }) { - const databaseEventTriggersToSync = triggersToSync.filter( - (trigger) => trigger.type === 'databaseEvent', - ); + private extractTriggerSettingsFromManifest( + triggers: ServerlessFunctionTriggerManifest[] = [], + ): { + cronTriggerSettings: CronTriggerSettings | null; + databaseEventTriggerSettings: DatabaseEventTriggerSettings | null; + httpRouteTriggerSettings: HttpRouteTriggerSettings | null; + } { + let cronTriggerSettings: CronTriggerSettings | null = null; + let databaseEventTriggerSettings: DatabaseEventTriggerSettings | null = + null; + let httpRouteTriggerSettings: HttpRouteTriggerSettings | null = null; - const { flatDatabaseEventTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatDatabaseEventTriggerMaps'], - }, - ); - - const existingDatabaseEventTriggers = Object.values( - flatDatabaseEventTriggerMaps.byId, - ).filter( - (trigger) => - isDefined(trigger) && - trigger.serverlessFunctionId === serverlessFunctionId, - ) as FlatDatabaseEventTrigger[]; - - const triggersToSyncUniversalIdentifiers = databaseEventTriggersToSync.map( - (trigger) => trigger.universalIdentifier, - ); - - const existingTriggersUniversalIdentifiers = - existingDatabaseEventTriggers.map( - (trigger) => trigger.universalIdentifier, - ); - - const triggersToDelete = existingDatabaseEventTriggers.filter( - (trigger) => - isDefined(trigger.universalIdentifier) && - !triggersToSyncUniversalIdentifiers.includes( - trigger.universalIdentifier, - ), - ); - - const triggersToUpdate = existingDatabaseEventTriggers.filter( - (trigger) => - isDefined(trigger.universalIdentifier) && - triggersToSyncUniversalIdentifiers.includes( - trigger.universalIdentifier, - ), - ); - - const triggersToCreate = databaseEventTriggersToSync.filter( - (triggerToSync) => - !existingTriggersUniversalIdentifiers.includes( - triggerToSync.universalIdentifier, - ), - ); - - for (const triggerToDelete of triggersToDelete) { - await this.databaseEventTriggerV2Service.destroyOne({ - destroyDatabaseEventTriggerInput: { id: triggerToDelete.id }, - workspaceId, - }); - } - - for (const triggerToUpdate of triggersToUpdate) { - const triggerToSync = databaseEventTriggersToSync.find( - (trigger) => - trigger.universalIdentifier === triggerToUpdate.universalIdentifier, - ); - - if (!triggerToSync || triggerToSync.type !== 'databaseEvent') { - throw new ApplicationException( - `Failed to find database event trigger to sync with universalIdentifier ${triggerToUpdate.universalIdentifier}`, - ApplicationExceptionCode.ENTITY_NOT_FOUND, - ); + for (const trigger of triggers) { + if (trigger.type === 'cron') { + cronTriggerSettings = { pattern: trigger.pattern }; + } else if (trigger.type === 'databaseEvent') { + databaseEventTriggerSettings = { + eventName: trigger.eventName, + updatedFields: trigger.updatedFields, + }; + } else if (trigger.type === 'route') { + httpRouteTriggerSettings = { + path: trigger.path, + httpMethod: trigger.httpMethod as HTTPMethod, + isAuthRequired: trigger.isAuthRequired, + forwardedRequestHeaders: trigger.forwardedRequestHeaders, + }; } - - const updateDatabaseEventTriggerInput = { - id: triggerToUpdate.id, - update: { - settings: { - eventName: triggerToSync.eventName, - updatedFields: triggerToSync.updatedFields, - }, - }, - }; - - await this.databaseEventTriggerV2Service.updateOne( - updateDatabaseEventTriggerInput, - workspaceId, - ); } - for (const triggerToCreate of triggersToCreate) { - if (triggerToCreate.type !== 'databaseEvent') { - continue; - } - - const createDatabaseEventTriggerInput = { - settings: { - eventName: triggerToCreate.eventName, - updatedFields: triggerToCreate.updatedFields, - }, - universalIdentifier: triggerToCreate.universalIdentifier, - serverlessFunctionId, - }; - - await this.databaseEventTriggerV2Service.createOne( - createDatabaseEventTriggerInput, - workspaceId, - applicationId, - ); - } - } - - private async syncCronTriggersForServerlessFunction({ - serverlessFunctionId, - triggersToSync, - workspaceId, - applicationId, - }: { - serverlessFunctionId: string; - triggersToSync: ServerlessFunctionTriggerManifest[]; - workspaceId: string; - applicationId: string; - }) { - const cronTriggersToSync = triggersToSync.filter( - (trigger) => trigger.type === 'cron', - ); - - const { flatCronTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatCronTriggerMaps'], - }, - ); - - const existingCronTriggers = Object.values(flatCronTriggerMaps.byId).filter( - (trigger) => - isDefined(trigger) && - trigger.serverlessFunctionId === serverlessFunctionId, - ) as FlatCronTrigger[]; - - const triggersToSyncUniversalIdentifiers = cronTriggersToSync.map( - (trigger) => trigger.universalIdentifier, - ); - - const existingTriggersUniversalIdentifiers = existingCronTriggers.map( - (trigger) => trigger.universalIdentifier, - ); - - const triggersToDelete = existingCronTriggers.filter( - (trigger) => - isDefined(trigger.universalIdentifier) && - !triggersToSyncUniversalIdentifiers.includes( - trigger.universalIdentifier, - ), - ); - - const triggersToUpdate = existingCronTriggers.filter( - (trigger) => - isDefined(trigger.universalIdentifier) && - triggersToSyncUniversalIdentifiers.includes( - trigger.universalIdentifier, - ), - ); - - const triggersToCreate = cronTriggersToSync.filter( - (triggerToSync) => - !existingTriggersUniversalIdentifiers.includes( - triggerToSync.universalIdentifier, - ), - ); - - for (const triggerToDelete of triggersToDelete) { - await this.cronTriggerV2Service.destroyOne({ - destroyCronTriggerInput: { id: triggerToDelete.id }, - workspaceId, - }); - } - - for (const triggerToUpdate of triggersToUpdate) { - const triggerToSync = cronTriggersToSync.find( - (trigger) => - trigger.universalIdentifier === triggerToUpdate.universalIdentifier, - ); - - if (!triggerToSync || triggerToSync.type !== 'cron') { - throw new ApplicationException( - `Failed to find cron trigger to sync with universalIdentifier ${triggerToUpdate.universalIdentifier}`, - ApplicationExceptionCode.ENTITY_NOT_FOUND, - ); - } - - const updateCronTriggerInput = { - id: triggerToUpdate.id, - update: { - settings: { - pattern: triggerToSync.pattern, - }, - }, - }; - - await this.cronTriggerV2Service.updateOne( - updateCronTriggerInput, - workspaceId, - ); - } - - for (const triggerToCreate of triggersToCreate) { - if (triggerToCreate.type !== 'cron') { - continue; - } - - const createCronTriggerInput = { - settings: { - pattern: triggerToCreate.pattern, - }, - universalIdentifier: triggerToCreate.universalIdentifier, - serverlessFunctionId, - }; - - await this.cronTriggerV2Service.createOne( - createCronTriggerInput, - workspaceId, - applicationId, - ); - } - } - - private async syncRouteTriggersForServerlessFunction({ - serverlessFunctionId, - triggersToSync, - workspaceId, - applicationId, - }: { - serverlessFunctionId: string; - triggersToSync: ServerlessFunctionTriggerManifest[]; - workspaceId: string; - applicationId: string; - }) { - const routeTriggersToSync = triggersToSync.filter( - (trigger) => trigger.type === 'route', - ); - - const { flatRouteTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatRouteTriggerMaps'], - }, - ); - - const existingRouteTriggers = Object.values( - flatRouteTriggerMaps.byId, - ).filter( - (trigger) => - isDefined(trigger) && - trigger.serverlessFunctionId === serverlessFunctionId, - ) as FlatRouteTrigger[]; - - const triggersToSyncUniversalIdentifiers = routeTriggersToSync.map( - (trigger) => trigger.universalIdentifier, - ); - - const existingTriggersUniversalIdentifiers = existingRouteTriggers.map( - (trigger) => trigger.universalIdentifier, - ); - - const triggersToDelete = existingRouteTriggers.filter( - (trigger) => - isDefined(trigger.universalIdentifier) && - !triggersToSyncUniversalIdentifiers.includes( - trigger.universalIdentifier, - ), - ); - - const triggersToUpdate = existingRouteTriggers.filter( - (trigger) => - isDefined(trigger.universalIdentifier) && - triggersToSyncUniversalIdentifiers.includes( - trigger.universalIdentifier, - ), - ); - - const triggersToCreate = routeTriggersToSync.filter( - (triggerToSync) => - !existingTriggersUniversalIdentifiers.includes( - triggerToSync.universalIdentifier, - ), - ); - - for (const triggerToDelete of triggersToDelete) { - await this.routeTriggerV2Service.destroyOne({ - destroyRouteTriggerInput: { id: triggerToDelete.id }, - workspaceId, - }); - } - - for (const triggerToUpdate of triggersToUpdate) { - const triggerToSync = routeTriggersToSync.find( - (trigger) => - trigger.universalIdentifier === triggerToUpdate.universalIdentifier, - ); - - if (!triggerToSync || triggerToSync.type !== 'route') { - throw new ApplicationException( - `Failed to find route trigger to sync with universalIdentifier ${triggerToUpdate.universalIdentifier}`, - ApplicationExceptionCode.ENTITY_NOT_FOUND, - ); - } - - const updateRouteTriggerInput = { - id: triggerToUpdate.id, - update: { - path: triggerToSync.path, - httpMethod: triggerToSync.httpMethod as HTTPMethod, - isAuthRequired: triggerToSync.isAuthRequired, - forwardedRequestHeaders: triggerToSync.forwardedRequestHeaders ?? [], - }, - }; - - await this.routeTriggerV2Service.updateOne( - updateRouteTriggerInput, - workspaceId, - ); - } - - for (const triggerToCreate of triggersToCreate) { - if (triggerToCreate.type !== 'route') { - continue; - } - - const createRouteTriggerInput = { - path: triggerToCreate.path, - httpMethod: triggerToCreate.httpMethod as HTTPMethod, - isAuthRequired: triggerToCreate.isAuthRequired, - forwardedRequestHeaders: triggerToCreate.forwardedRequestHeaders ?? [], - serverlessFunctionId, - }; - - await this.routeTriggerV2Service.createOne( - createRouteTriggerInput, - workspaceId, - applicationId, - ); - } + return { + cronTriggerSettings, + databaseEventTriggerSettings, + httpRouteTriggerSettings, + }; } public async uninstallApplication({ diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/constants/flat-cron-trigger-editable-properties.constant.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/constants/flat-cron-trigger-editable-properties.constant.ts deleted file mode 100644 index 09b0c8c1ff..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/constants/flat-cron-trigger-editable-properties.constant.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { type FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; - -export const FLAT_CRON_TRIGGER_EDITABLE_PROPERTIES = [ - 'settings', -] as const satisfies (keyof FlatCronTrigger)[]; diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/cron-trigger.module.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/cron-trigger.module.ts index ebc7d180c1..ad16f8cb67 100644 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/cron-trigger.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/cron-trigger.module.ts @@ -1,37 +1,16 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { CronTriggerCronCommand } from 'src/engine/metadata-modules/cron-trigger/crons/commands/cron-trigger.cron.command'; import { CronTriggerCronJob } from 'src/engine/metadata-modules/cron-trigger/crons/jobs/cron-trigger.cron.job'; -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { CronTriggerResolver } from 'src/engine/metadata-modules/cron-trigger/resolvers/cron-trigger.resolver'; -import { CronTriggerV2Service } from 'src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service'; -import { WorkspaceFlatCronTriggerMapCacheService } from 'src/engine/metadata-modules/cron-trigger/services/workspace-flat-cron-trigger-map-cache.service'; -import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module'; -import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; -import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module'; +import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; @Module({ imports: [ - TypeOrmModule.forFeature([WorkspaceEntity, CronTriggerEntity]), - ApplicationModule, - WorkspaceManyOrAllFlatEntityMapsCacheModule, - PermissionsModule, - WorkspaceMigrationModule, - ], - providers: [ - CronTriggerCronJob, - CronTriggerCronCommand, - CronTriggerResolver, - CronTriggerV2Service, - WorkspaceFlatCronTriggerMapCacheService, - ], - exports: [ - CronTriggerCronCommand, - CronTriggerV2Service, - WorkspaceFlatCronTriggerMapCacheService, + TypeOrmModule.forFeature([WorkspaceEntity, ServerlessFunctionEntity]), ], + providers: [CronTriggerCronJob, CronTriggerCronCommand], + exports: [CronTriggerCronCommand], }) export class CronTriggerModule {} diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/crons/jobs/cron-trigger.cron.job.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/crons/jobs/cron-trigger.cron.job.ts index 65527931a1..9c717d7fa3 100644 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/crons/jobs/cron-trigger.cron.job.ts +++ b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/crons/jobs/cron-trigger.cron.job.ts @@ -2,7 +2,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { isDefined } from 'twenty-shared/utils'; import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; -import { Repository } from 'typeorm'; +import { IsNull, Not, Repository } from 'typeorm'; import { SentryCronMonitor } from 'src/engine/core-modules/cron/sentry-cron-monitor.decorator'; import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator'; @@ -11,11 +11,11 @@ import { Processor } from 'src/engine/core-modules/message-queue/decorators/proc import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; import { ServerlessFunctionTriggerJob, ServerlessFunctionTriggerJobData, } from 'src/engine/metadata-modules/serverless-function/jobs/serverless-function-trigger.job'; +import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; import { shouldRunNow } from 'src/utils/should-run-now.utils'; export const CRON_TRIGGER_CRON_PATTERN = '* * * * *'; @@ -27,8 +27,8 @@ export class CronTriggerCronJob { private readonly messageQueueService: MessageQueueService, @InjectRepository(WorkspaceEntity) private readonly workspaceRepository: Repository, - @InjectRepository(CronTriggerEntity) - private readonly cronTriggerRepository: Repository, + @InjectRepository(ServerlessFunctionEntity) + private readonly serverlessFunctionRepository: Repository, ) {} @Process(CronTriggerCronJob.name) @@ -44,22 +44,23 @@ export class CronTriggerCronJob { const now = new Date(); for (const activeWorkspace of activeWorkspaces) { - const cronTriggers = await this.cronTriggerRepository.find({ - where: { - workspaceId: activeWorkspace.id, - }, - select: ['id', 'settings', 'workspaceId'], - relations: ['serverlessFunction'], - }); + const serverlessFunctionsWithCronTrigger = + await this.serverlessFunctionRepository.find({ + where: { + workspaceId: activeWorkspace.id, + cronTriggerSettings: Not(IsNull()), + }, + select: ['id', 'cronTriggerSettings', 'workspaceId'], + }); - for (const cronTrigger of cronTriggers) { - const settings = cronTrigger.settings; + for (const serverlessFunction of serverlessFunctionsWithCronTrigger) { + const cronSettings = serverlessFunction.cronTriggerSettings; - if (!isDefined(settings.pattern)) { + if (!isDefined(cronSettings?.pattern)) { continue; } - if (!shouldRunNow(settings.pattern, now)) { + if (!shouldRunNow(cronSettings.pattern, now)) { continue; } @@ -67,8 +68,8 @@ export class CronTriggerCronJob { ServerlessFunctionTriggerJob.name, [ { - serverlessFunctionId: cronTrigger.serverlessFunction.id, - workspaceId: cronTrigger.workspaceId, + serverlessFunctionId: serverlessFunction.id, + workspaceId: serverlessFunction.workspaceId, payload: {}, }, ], diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/create-cron-trigger.input.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/create-cron-trigger.input.ts deleted file mode 100644 index d3c634c8a9..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/create-cron-trigger.input.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Field, HideField, InputType } from '@nestjs/graphql'; - -import { IsNotEmpty, IsObject, IsUUID } 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 CreateCronTriggerInput { - @IsObject() - @IsNotEmpty() - @Field(() => GraphQLJSON) - settings: CronTriggerSettings; - - @IsUUID() - @IsNotEmpty() - @Field() - serverlessFunctionId: string; - - @HideField() - universalIdentifier?: string; - - @HideField() - applicationId?: string; -} diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/cron-trigger-id.input.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/cron-trigger-id.input.ts deleted file mode 100644 index 67400d80e5..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/cron-trigger-id.input.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Field, InputType } from '@nestjs/graphql'; - -import { IsNotEmpty, IsUUID } from 'class-validator'; - -@InputType() -export class CronTriggerIdInput { - @IsUUID() - @IsNotEmpty() - @Field(() => String) - id: string; -} diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/cron-trigger.dto.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/cron-trigger.dto.ts deleted file mode 100644 index 06d39cf4be..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/cron-trigger.dto.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Field, ObjectType } from '@nestjs/graphql'; - -import { IDField } from '@ptc-org/nestjs-query-graphql'; -import { IsDateString, IsNotEmpty, IsObject, IsUUID } from 'class-validator'; -import GraphQLJSON from 'graphql-type-json'; - -import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; -import { CronTriggerSettings } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; - -@ObjectType('CronTrigger') -export class CronTriggerDTO { - @IsUUID() - @IsNotEmpty() - @IDField(() => UUIDScalarType) - id: string; - - @IsObject() - @Field(() => GraphQLJSON) - settings: CronTriggerSettings; - - @IsDateString() - @Field() - createdAt: Date; - - @IsDateString() - @Field() - updatedAt: Date; -} 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 deleted file mode 100644 index 0fd4b59e62..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/dtos/update-cron-trigger.input.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Field, InputType } from '@nestjs/graphql'; - -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() -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 deleted file mode 100644 index 002879f6d4..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - Column, - CreateDateColumn, - Entity, - Index, - JoinColumn, - ManyToOne, - PrimaryGeneratedColumn, - Relation, - UpdateDateColumn, -} from 'typeorm'; - -import { type JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type'; -import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; -import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface'; - -export type CronTriggerSettings = { - pattern: string; -}; - -@Entity({ name: 'cronTrigger', schema: 'core' }) -@Index('IDX_CRON_TRIGGER_WORKSPACE_ID', ['workspaceId']) -@Index('IDX_CRON_TRIGGER_SERVERLESS_FUNCTION_ID', ['serverlessFunctionId']) -export class CronTriggerEntity - extends SyncableEntity - implements Required -{ - @PrimaryGeneratedColumn('uuid') - id: string; - - @Column({ nullable: false, type: 'jsonb' }) - settings: JsonbProperty; - - @ManyToOne( - () => ServerlessFunctionEntity, - (serverlessFunction) => serverlessFunction.cronTriggers, - { onDelete: 'CASCADE' }, - ) - @JoinColumn({ name: 'serverlessFunctionId' }) - serverlessFunction: Relation; - - @Column({ nullable: false, type: 'uuid' }) - serverlessFunctionId: string; - - @CreateDateColumn({ type: 'timestamptz' }) - createdAt: Date; - - @UpdateDateColumn({ type: 'timestamptz' }) - updatedAt: Date; -} 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 deleted file mode 100644 index a136349d97..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { type MessageDescriptor } from '@lingui/core'; -import { msg } from '@lingui/core/macro'; -import { assertUnreachable } from 'twenty-shared/utils'; - -import { CustomException } from 'src/utils/custom-exception'; - -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', -} - -const getCronTriggerExceptionUserFriendlyMessage = ( - code: CronTriggerExceptionCode, -) => { - switch (code) { - case CronTriggerExceptionCode.CRON_TRIGGER_NOT_FOUND: - return msg`Cron trigger not found.`; - case CronTriggerExceptionCode.CRON_TRIGGER_ALREADY_EXIST: - return msg`Cron trigger already exists.`; - case CronTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND: - return msg`Serverless function not found.`; - default: - assertUnreachable(code); - } -}; - -export class CronTriggerException extends CustomException { - constructor( - message: string, - code: CronTriggerExceptionCode, - { userFriendlyMessage }: { userFriendlyMessage?: MessageDescriptor } = {}, - ) { - super(message, code, { - userFriendlyMessage: - userFriendlyMessage ?? getCronTriggerExceptionUserFriendlyMessage(code), - }); - } -} diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/resolvers/cron-trigger.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/resolvers/cron-trigger.resolver.ts deleted file mode 100644 index 632256f4fb..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/resolvers/cron-trigger.resolver.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; -import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; - -import { PermissionFlagType } from 'twenty-shared/constants'; -import { isDefined } from 'twenty-shared/utils'; - -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 { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; -import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; -import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { CreateCronTriggerInput } from 'src/engine/metadata-modules/cron-trigger/dtos/create-cron-trigger.input'; -import { CronTriggerIdInput } from 'src/engine/metadata-modules/cron-trigger/dtos/cron-trigger-id.input'; -import { CronTriggerDTO } from 'src/engine/metadata-modules/cron-trigger/dtos/cron-trigger.dto'; -import { UpdateCronTriggerInput } from 'src/engine/metadata-modules/cron-trigger/dtos/update-cron-trigger.input'; -import { - CronTriggerException, - CronTriggerExceptionCode, -} from 'src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception'; -import { CronTriggerV2Service } from 'src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service'; -import { cronTriggerGraphQLApiExceptionHandler } from 'src/engine/metadata-modules/cron-trigger/utils/cron-trigger-graphql-api-exception-handler.util'; -import { fromFlatCronTriggerToCronTriggerDto } from 'src/engine/metadata-modules/cron-trigger/utils/from-flat-cron-trigger-to-cron-trigger-dto.util'; -import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; - -@UseGuards( - WorkspaceAuthGuard, - SettingsPermissionGuard(PermissionFlagType.WORKFLOWS), -) -@Resolver() -@UsePipes(ResolverValidationPipe) -@UseFilters(PreventNestToAutoLogGraphqlErrorsFilter) -export class CronTriggerResolver { - constructor( - private readonly cronTriggerV2Service: CronTriggerV2Service, - private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService, - ) {} - - @Query(() => CronTriggerDTO) - async findOneCronTrigger( - @Args('input') { id }: CronTriggerIdInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const { flatCronTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatCronTriggerMaps'], - }, - ); - - const flatCronTrigger = findFlatEntityByIdInFlatEntityMaps({ - flatEntityId: id, - flatEntityMaps: flatCronTriggerMaps, - }); - - if (!isDefined(flatCronTrigger)) { - throw new CronTriggerException( - `Cron trigger with id ${id} not found`, - CronTriggerExceptionCode.CRON_TRIGGER_NOT_FOUND, - ); - } - - return fromFlatCronTriggerToCronTriggerDto(flatCronTrigger); - } catch (error) { - return cronTriggerGraphQLApiExceptionHandler(error); - } - } - - @Query(() => [CronTriggerDTO]) - async findManyCronTriggers( - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const { flatCronTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatCronTriggerMaps'], - }, - ); - - return Object.values(flatCronTriggerMaps.byId) - .filter(isDefined) - .map(fromFlatCronTriggerToCronTriggerDto); - } catch (error) { - return cronTriggerGraphQLApiExceptionHandler(error); - } - } - - @Mutation(() => CronTriggerDTO) - async deleteOneCronTrigger( - @Args('input') input: CronTriggerIdInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const flatCronTrigger = await this.cronTriggerV2Service.destroyOne({ - destroyCronTriggerInput: input, - workspaceId, - }); - - return fromFlatCronTriggerToCronTriggerDto(flatCronTrigger); - } catch (error) { - return cronTriggerGraphQLApiExceptionHandler(error); - } - } - - @Mutation(() => CronTriggerDTO) - async updateOneCronTrigger( - @Args('input') - input: UpdateCronTriggerInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const flatCronTrigger = await this.cronTriggerV2Service.updateOne( - input, - workspaceId, - ); - - return fromFlatCronTriggerToCronTriggerDto(flatCronTrigger); - } catch (error) { - return cronTriggerGraphQLApiExceptionHandler(error); - } - } - - @Mutation(() => CronTriggerDTO) - async createOneCronTrigger( - @Args('input') - input: CreateCronTriggerInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const flatCronTrigger = await this.cronTriggerV2Service.createOne( - input, - workspaceId, - ); - - return fromFlatCronTriggerToCronTriggerDto(flatCronTrigger); - } catch (error) { - return cronTriggerGraphQLApiExceptionHandler(error); - } - } -} 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 deleted file mode 100644 index a71d57bf0f..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/cron-trigger-v2.service.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { isDefined } from 'twenty-shared/utils'; - -import { ApplicationService } from 'src/engine/core-modules/application/application.service'; -import { CreateCronTriggerInput } from 'src/engine/metadata-modules/cron-trigger/dtos/create-cron-trigger.input'; -import { CronTriggerIdInput } from 'src/engine/metadata-modules/cron-trigger/dtos/cron-trigger-id.input'; -import { UpdateCronTriggerInput } from 'src/engine/metadata-modules/cron-trigger/dtos/update-cron-trigger.input'; -import { - CronTriggerException, - CronTriggerExceptionCode, -} from 'src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception'; -import { type FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; -import { fromCreateCronTriggerInputToFlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/utils/from-create-cron-trigger-input-to-flat-cron-trigger.util'; -import { fromUpdateCronTriggerInputToFlatCronTriggerToUpdateOrThrow } from 'src/engine/metadata-modules/cron-trigger/utils/from-update-cron-trigger-input-to-flat-cron-trigger-to-update-or-throw.util'; -import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; -import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception'; -import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service'; - -@Injectable() -export class CronTriggerV2Service { - constructor( - private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService, - private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, - private readonly applicationService: ApplicationService, - ) {} - - async createOne( - cronTriggerInput: CreateCronTriggerInput, - workspaceId: string, - /** - * @deprecated do not use call validateBuildAndRunWorkspaceMigration contextually - * when interacting with another application than workspace custom one - * */ - applicationId?: string, - ): Promise { - const { workspaceCustomFlatApplication } = - await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow( - { - workspaceId, - }, - ); - - const flatCronTriggerToCreate = fromCreateCronTriggerInputToFlatCronTrigger( - { - createCronTriggerInput: cronTriggerInput, - workspaceId, - workspaceCustomApplicationId: - applicationId ?? workspaceCustomFlatApplication.id, - }, - ); - - const validateAndBuildResult = - await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( - { - allFlatEntityOperationByMetadataName: { - cronTrigger: { - flatEntityToCreate: [flatCronTriggerToCreate], - flatEntityToDelete: [], - flatEntityToUpdate: [], - }, - }, - workspaceId, - isSystemBuild: false, - }, - ); - - if (isDefined(validateAndBuildResult)) { - throw new WorkspaceMigrationBuilderException( - validateAndBuildResult, - 'Multiple validation errors occurred while creating cron trigger', - ); - } - - const { flatCronTriggerMaps: recomputedExistingFlatCronTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatCronTriggerMaps', 'flatServerlessFunctionMaps'], - }, - ); - - return findFlatEntityByIdInFlatEntityMapsOrThrow({ - flatEntityId: flatCronTriggerToCreate.id, - flatEntityMaps: recomputedExistingFlatCronTriggerMaps, - }); - } - - async updateOne( - cronTriggerInput: UpdateCronTriggerInput, - workspaceId: string, - ): Promise { - const { flatCronTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatCronTriggerMaps'], - }, - ); - - const optimisticallyUpdatedFlatCronTrigger = - fromUpdateCronTriggerInputToFlatCronTriggerToUpdateOrThrow({ - flatCronTriggerMaps, - updateCronTriggerInput: cronTriggerInput, - }); - - const validateAndBuildResult = - await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( - { - allFlatEntityOperationByMetadataName: { - cronTrigger: { - flatEntityToCreate: [], - flatEntityToDelete: [], - flatEntityToUpdate: [optimisticallyUpdatedFlatCronTrigger], - }, - }, - workspaceId, - isSystemBuild: false, - }, - ); - - if (isDefined(validateAndBuildResult)) { - throw new WorkspaceMigrationBuilderException( - validateAndBuildResult, - 'Multiple validation errors occurred while updating cron trigger', - ); - } - - const { flatCronTriggerMaps: recomputedExistingFlatCronTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatCronTriggerMaps'], - }, - ); - - return findFlatEntityByIdInFlatEntityMapsOrThrow({ - flatEntityId: optimisticallyUpdatedFlatCronTrigger.id, - flatEntityMaps: recomputedExistingFlatCronTriggerMaps, - }); - } - - async destroyOne({ - destroyCronTriggerInput, - workspaceId, - }: { - destroyCronTriggerInput: CronTriggerIdInput; - workspaceId: string; - }): Promise { - const { flatCronTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatCronTriggerMaps'], - }, - ); - - const existingFlatCronTrigger = - flatCronTriggerMaps.byId[destroyCronTriggerInput.id]; - - if (!isDefined(existingFlatCronTrigger)) { - throw new CronTriggerException( - 'Cron trigger to destroy not found', - CronTriggerExceptionCode.CRON_TRIGGER_NOT_FOUND, - ); - } - - const validateAndBuildResult = - await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( - { - allFlatEntityOperationByMetadataName: { - cronTrigger: { - flatEntityToCreate: [], - flatEntityToDelete: [existingFlatCronTrigger], - flatEntityToUpdate: [], - }, - }, - workspaceId, - isSystemBuild: false, - }, - ); - - if (isDefined(validateAndBuildResult)) { - throw new WorkspaceMigrationBuilderException( - validateAndBuildResult, - 'Multiple validation errors occurred while destroying cron trigger', - ); - } - - return existingFlatCronTrigger; - } -} diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/workspace-flat-cron-trigger-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/workspace-flat-cron-trigger-map-cache.service.ts deleted file mode 100644 index 689e25d513..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/services/workspace-flat-cron-trigger-map-cache.service.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; - -import { removePropertiesFromRecord } from 'twenty-shared/utils'; -import { Repository } from 'typeorm'; - -import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service'; - -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; -import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant'; -import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { getMetadataEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-entity-relation-properties.util'; -import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator'; -import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util'; - -@Injectable() -@WorkspaceCache('flatCronTriggerMaps') -export class WorkspaceFlatCronTriggerMapCacheService extends WorkspaceCacheProvider< - FlatEntityMaps -> { - constructor( - @InjectRepository(CronTriggerEntity) - private readonly cronTriggerRepository: Repository, - ) { - super(); - } - - async computeForCache( - workspaceId: string, - ): Promise> { - const cronTriggers = await this.cronTriggerRepository.find({ - where: { - workspaceId, - }, - }); - - const flatCronTriggerMaps = createEmptyFlatEntityMaps(); - - for (const cronTriggerEntity of cronTriggers) { - const flatCronTrigger = { - ...removePropertiesFromRecord( - cronTriggerEntity, - getMetadataEntityRelationProperties('cronTrigger'), - ), - universalIdentifier: cronTriggerEntity.universalIdentifier, - createdAt: cronTriggerEntity.createdAt.toISOString(), - updatedAt: cronTriggerEntity.updatedAt.toISOString(), - } satisfies FlatCronTrigger; - - addFlatEntityToFlatEntityMapsThroughMutationOrThrow({ - flatEntity: flatCronTrigger, - flatEntityMapsToMutate: flatCronTriggerMaps, - }); - } - - return flatCronTriggerMaps; - } -} diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger-properties-to-compare.type.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger-properties-to-compare.type.ts deleted file mode 100644 index 0dc240210f..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger-properties-to-compare.type.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { type FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; - -export type FlatCronTriggerPropertiesToCompare = keyof Pick< - FlatCronTrigger, - 'settings' ->; diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type.ts deleted file mode 100644 index a0f5bf94a0..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { type CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; - -export type FlatCronTrigger = FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/cron-trigger-graphql-api-exception-handler.util.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/cron-trigger-graphql-api-exception-handler.util.ts deleted file mode 100644 index 707a7b5c5e..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/cron-trigger-graphql-api-exception-handler.util.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - ConflictError, - NotFoundError, -} from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; -import { - CronTriggerException, - CronTriggerExceptionCode, -} from 'src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception'; - -export const cronTriggerGraphQLApiExceptionHandler = (error: Error): never => { - if (error instanceof CronTriggerException) { - switch (error.code) { - case CronTriggerExceptionCode.CRON_TRIGGER_NOT_FOUND: - throw new NotFoundError('Cron trigger not found'); - case CronTriggerExceptionCode.CRON_TRIGGER_ALREADY_EXIST: - throw new ConflictError('Cron trigger already exists'); - default: - throw error; - } - } - - throw error; -}; diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/cron-trigger-graphql-api-exception-handler.utils.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/cron-trigger-graphql-api-exception-handler.utils.ts deleted file mode 100644 index 96fdd0a7f8..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/cron-trigger-graphql-api-exception-handler.utils.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { CronTriggerException } from 'src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception'; - -export const cronTriggerGraphqlApiExceptionHandler = (error: Error) => { - if (error instanceof CronTriggerException) { - throw error; - } - - throw error; -}; diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-create-cron-trigger-input-to-flat-cron-trigger.util.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-create-cron-trigger-input-to-flat-cron-trigger.util.ts deleted file mode 100644 index dda4e55733..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-create-cron-trigger-input-to-flat-cron-trigger.util.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { v4 } from 'uuid'; - -import { type CreateCronTriggerInput } from 'src/engine/metadata-modules/cron-trigger/dtos/create-cron-trigger.input'; -import { type FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; - -export const fromCreateCronTriggerInputToFlatCronTrigger = ({ - createCronTriggerInput, - workspaceId, - workspaceCustomApplicationId, -}: { - createCronTriggerInput: CreateCronTriggerInput; - workspaceId: string; - workspaceCustomApplicationId: string; -}): FlatCronTrigger => { - const now = new Date().toISOString(); - const id = v4(); - - return { - id, - universalIdentifier: createCronTriggerInput.universalIdentifier ?? v4(), - settings: createCronTriggerInput.settings, - serverlessFunctionId: createCronTriggerInput.serverlessFunctionId, - applicationId: workspaceCustomApplicationId, - workspaceId, - createdAt: now, - updatedAt: now, - }; -}; diff --git a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-flat-cron-trigger-to-cron-trigger-dto.util.ts b/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-flat-cron-trigger-to-cron-trigger-dto.util.ts deleted file mode 100644 index c98120c3a6..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/cron-trigger/utils/from-flat-cron-trigger-to-cron-trigger-dto.util.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { type CronTriggerDTO } from 'src/engine/metadata-modules/cron-trigger/dtos/cron-trigger.dto'; -import { type FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; - -export const fromFlatCronTriggerToCronTriggerDto = ( - flatCronTrigger: FlatCronTrigger, -): CronTriggerDTO => ({ - id: flatCronTrigger.id, - settings: flatCronTrigger.settings, - createdAt: new Date(flatCronTrigger.createdAt), - updatedAt: new Date(flatCronTrigger.updatedAt), -}); 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 deleted file mode 100644 index 5a9e025854..0000000000 --- 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 +++ /dev/null @@ -1,31 +0,0 @@ -import { type UpdateCronTriggerInput } from 'src/engine/metadata-modules/cron-trigger/dtos/update-cron-trigger.input'; -import { - CronTriggerException, - CronTriggerExceptionCode, -} from 'src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception'; -import { type FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; -import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; - -export const fromUpdateCronTriggerInputToFlatCronTriggerToUpdateOrThrow = ({ - flatCronTriggerMaps, - updateCronTriggerInput, -}: { - flatCronTriggerMaps: FlatEntityMaps; - updateCronTriggerInput: UpdateCronTriggerInput; -}): FlatCronTrigger => { - const existingFlatCronTrigger = - flatCronTriggerMaps.byId[updateCronTriggerInput.id]; - - if (!existingFlatCronTrigger) { - throw new CronTriggerException( - 'Cron trigger not found', - CronTriggerExceptionCode.CRON_TRIGGER_NOT_FOUND, - ); - } - - return { - ...existingFlatCronTrigger, - settings: updateCronTriggerInput.update.settings, - updatedAt: new Date().toISOString(), - }; -}; diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/constants/flat-database-event-trigger-editable-properties.constant.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/constants/flat-database-event-trigger-editable-properties.constant.ts deleted file mode 100644 index 674a61ea15..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/constants/flat-database-event-trigger-editable-properties.constant.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { type FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; - -export const FLAT_DATABASE_EVENT_TRIGGER_EDITABLE_PROPERTIES = [ - 'settings', -] as const satisfies (keyof FlatDatabaseEventTrigger)[]; diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/database-event-trigger.module.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/database-event-trigger.module.ts index b6b864d5ed..9d1ae2f952 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/database-event-trigger.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/database-event-trigger.module.ts @@ -1,31 +1,12 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; import { CallDatabaseEventTriggerJobsJob } from 'src/engine/metadata-modules/database-event-trigger/jobs/call-database-event-trigger-jobs.job'; -import { DatabaseEventTriggerResolver } from 'src/engine/metadata-modules/database-event-trigger/resolvers/database-event-trigger.resolver'; -import { DatabaseEventTriggerV2Service } from 'src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service'; -import { WorkspaceFlatDatabaseEventTriggerMapCacheService } from 'src/engine/metadata-modules/database-event-trigger/services/workspace-flat-database-event-trigger-map-cache.service'; -import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module'; -import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; -import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module'; +import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; @Module({ - imports: [ - TypeOrmModule.forFeature([WorkspaceEntity, DatabaseEventTriggerEntity]), - ApplicationModule, - WorkspaceManyOrAllFlatEntityMapsCacheModule, - PermissionsModule, - WorkspaceMigrationModule, - ], - providers: [ - CallDatabaseEventTriggerJobsJob, - DatabaseEventTriggerV2Service, - DatabaseEventTriggerResolver, - WorkspaceFlatDatabaseEventTriggerMapCacheService, - ], - exports: [DatabaseEventTriggerV2Service], + imports: [TypeOrmModule.forFeature([ServerlessFunctionEntity])], + providers: [CallDatabaseEventTriggerJobsJob], + exports: [], }) export class DatabaseEventTriggerModule {} diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/create-database-event-trigger.input.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/create-database-event-trigger.input.ts deleted file mode 100644 index 29dc253c43..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/create-database-event-trigger.input.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Field, HideField, InputType } from '@nestjs/graphql'; - -import { IsNotEmpty, IsObject, IsUUID } 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 CreateDatabaseEventTriggerInput { - @IsObject() - @IsNotEmpty() - @Field(() => GraphQLJSON) - settings: DatabaseEventTriggerSettings; - - @IsUUID() - @IsNotEmpty() - @Field() - serverlessFunctionId: string; - - @HideField() - universalIdentifier?: string; - - @HideField() - applicationId?: string; -} diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger-id.input.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger-id.input.ts deleted file mode 100644 index e3fb3641c9..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger-id.input.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Field, InputType } from '@nestjs/graphql'; - -import { IsNotEmpty, IsUUID } from 'class-validator'; - -@InputType() -export class DatabaseEventTriggerIdInput { - @IsUUID() - @IsNotEmpty() - @Field() - id: string; -} diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger.dto.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger.dto.ts deleted file mode 100644 index cec4ecbaeb..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger.dto.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Field, ObjectType } from '@nestjs/graphql'; - -import { IDField } from '@ptc-org/nestjs-query-graphql'; -import { IsDateString, IsNotEmpty, IsObject, IsUUID } from 'class-validator'; -import GraphQLJSON from 'graphql-type-json'; - -import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; -import { DatabaseEventTriggerSettings } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; - -@ObjectType('DatabaseEventTrigger') -export class DatabaseEventTriggerDTO { - @IsUUID() - @IsNotEmpty() - @IDField(() => UUIDScalarType) - id: string; - - @IsObject() - @Field(() => GraphQLJSON) - settings: DatabaseEventTriggerSettings; - - @IsDateString() - @Field() - createdAt: Date; - - @IsDateString() - @Field() - updatedAt: 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 deleted file mode 100644 index 6cc4e408eb..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/dtos/update-database-event-trigger.input.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Field, InputType } from '@nestjs/graphql'; - -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() -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 deleted file mode 100644 index 9927becacc..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { - Column, - CreateDateColumn, - Entity, - Index, - JoinColumn, - ManyToOne, - PrimaryGeneratedColumn, - Relation, - UpdateDateColumn, -} from 'typeorm'; - -import { type JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type'; -import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; -import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface'; - -export type DatabaseEventTriggerSettings = { - eventName: string; - updatedFields?: string[]; -}; - -@Entity('databaseEventTrigger') -@Index('IDX_DATABASE_EVENT_TRIGGER_WORKSPACE_ID', ['workspaceId']) -@Index('IDX_DATABASE_EVENT_TRIGGER_SERVERLESS_FUNCTION_ID', [ - 'serverlessFunctionId', -]) -export class DatabaseEventTriggerEntity - extends SyncableEntity - implements Required -{ - @PrimaryGeneratedColumn('uuid') - id: string; - - @Column({ nullable: false, type: 'jsonb' }) - settings: JsonbProperty; - - @ManyToOne( - () => ServerlessFunctionEntity, - (serverlessFunction) => serverlessFunction.databaseEventTriggers, - { onDelete: 'CASCADE' }, - ) - @JoinColumn({ name: 'serverlessFunctionId' }) - serverlessFunction: Relation; - - @Column({ nullable: false, type: 'uuid' }) - serverlessFunctionId: string; - - @CreateDateColumn({ type: 'timestamptz' }) - createdAt: Date; - - @UpdateDateColumn({ type: 'timestamptz' }) - updatedAt: Date; -} 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 deleted file mode 100644 index b28cc626e1..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { type MessageDescriptor } from '@lingui/core'; -import { msg } from '@lingui/core/macro'; -import { assertUnreachable } from 'twenty-shared/utils'; - -import { CustomException } from 'src/utils/custom-exception'; - -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', -} - -const getDatabaseEventTriggerExceptionUserFriendlyMessage = ( - code: DatabaseEventTriggerExceptionCode, -) => { - switch (code) { - case DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_NOT_FOUND: - return msg`Database event trigger not found.`; - case DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_ALREADY_EXIST: - return msg`Database event trigger already exists.`; - case DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_INVALID: - return msg`Invalid database event trigger.`; - case DatabaseEventTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND: - return msg`Serverless function not found.`; - default: - assertUnreachable(code); - } -}; - -export class DatabaseEventTriggerException extends CustomException { - constructor( - message: string, - code: DatabaseEventTriggerExceptionCode, - { userFriendlyMessage }: { userFriendlyMessage?: MessageDescriptor } = {}, - ) { - super(message, code, { - userFriendlyMessage: - userFriendlyMessage ?? - getDatabaseEventTriggerExceptionUserFriendlyMessage(code), - }); - } -} diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/jobs/call-database-event-trigger-jobs.job.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/jobs/call-database-event-trigger-jobs.job.ts index f71f581ad1..96c827e76d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/jobs/call-database-event-trigger-jobs.job.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/jobs/call-database-event-trigger-jobs.job.ts @@ -1,7 +1,8 @@ import { InjectRepository } from '@nestjs/typeorm'; import chunk from 'lodash.chunk'; -import { Repository } from 'typeorm'; +import { isDefined } from 'twenty-shared/utils'; +import { IsNull, Not, Repository } from 'typeorm'; import type { ObjectRecordEvent } from 'twenty-shared/database-events'; @@ -10,12 +11,12 @@ import { Process } from 'src/engine/core-modules/message-queue/decorators/proces import { Processor } from 'src/engine/core-modules/message-queue/decorators/processor.decorator'; import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants'; import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service'; -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; import { transformEventBatchToEventPayloads } from 'src/engine/metadata-modules/database-event-trigger/utils/transform-event-batch-to-event-payloads'; import { ServerlessFunctionTriggerJob, ServerlessFunctionTriggerJobData, } from 'src/engine/metadata-modules/serverless-function/jobs/serverless-function-trigger.job'; +import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event-batch.type'; const DATABASE_EVENT_JOBS_CHUNK_SIZE = 20; @@ -25,31 +26,33 @@ export class CallDatabaseEventTriggerJobsJob { constructor( @InjectMessageQueue(MessageQueue.serverlessFunctionQueue) private readonly messageQueueService: MessageQueueService, - @InjectRepository(DatabaseEventTriggerEntity) - private readonly databaseEventTriggerRepository: Repository, + @InjectRepository(ServerlessFunctionEntity) + private readonly serverlessFunctionRepository: Repository, ) {} @Process(CallDatabaseEventTriggerJobsJob.name) async handle(workspaceEventBatch: WorkspaceEventBatch) { - const databaseEventListeners = - await this.databaseEventTriggerRepository.find({ + const serverlessFunctionsWithDatabaseEventTrigger = + await this.serverlessFunctionRepository.find({ where: { workspaceId: workspaceEventBatch.workspaceId, + databaseEventTriggerSettings: Not(IsNull()), }, - select: ['id', 'settings', 'workspaceId'], - relations: ['serverlessFunction'], + select: ['id', 'databaseEventTriggerSettings', 'workspaceId'], }); - const databaseEventListenersToTrigger = databaseEventListeners.filter( - (databaseEventListener) => + const serverlessFunctionsToTrigger = + serverlessFunctionsWithDatabaseEventTrigger.filter((serverlessFunction) => this.shouldTriggerJob({ workspaceEventBatch, - eventName: databaseEventListener.settings.eventName, + eventName: isDefined(serverlessFunction.databaseEventTriggerSettings) + ? serverlessFunction.databaseEventTriggerSettings.eventName + : '', }), - ); + ); const serverlessFunctionPayloads = transformEventBatchToEventPayloads({ - databaseEventListeners: databaseEventListenersToTrigger, + serverlessFunctions: serverlessFunctionsToTrigger, workspaceEventBatch, }); diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/resolvers/database-event-trigger.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/resolvers/database-event-trigger.resolver.ts deleted file mode 100644 index 1f216cecd0..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/resolvers/database-event-trigger.resolver.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; -import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; - -import { PermissionFlagType } from 'twenty-shared/constants'; -import { isDefined } from 'twenty-shared/utils'; - -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 { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; -import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; -import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { CreateDatabaseEventTriggerInput } from 'src/engine/metadata-modules/database-event-trigger/dtos/create-database-event-trigger.input'; -import { DatabaseEventTriggerIdInput } from 'src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger-id.input'; -import { DatabaseEventTriggerDTO } from 'src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger.dto'; -import { UpdateDatabaseEventTriggerInput } from 'src/engine/metadata-modules/database-event-trigger/dtos/update-database-event-trigger.input'; -import { - DatabaseEventTriggerException, - DatabaseEventTriggerExceptionCode, -} from 'src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception'; -import { DatabaseEventTriggerV2Service } from 'src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service'; -import { databaseEventTriggerGraphQLApiExceptionHandler } from 'src/engine/metadata-modules/database-event-trigger/utils/database-event-trigger-graphql-api-exception-handler.utils'; -import { fromFlatDatabaseEventTriggerToDatabaseEventTriggerDto } from 'src/engine/metadata-modules/database-event-trigger/utils/from-flat-database-event-trigger-to-database-event-trigger-dto.util'; -import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; - -@UseGuards( - WorkspaceAuthGuard, - SettingsPermissionGuard(PermissionFlagType.WORKFLOWS), -) -@Resolver() -@UsePipes(ResolverValidationPipe) -@UseFilters(PreventNestToAutoLogGraphqlErrorsFilter) -export class DatabaseEventTriggerResolver { - constructor( - private readonly databaseEventTriggerV2Service: DatabaseEventTriggerV2Service, - private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService, - ) {} - - @Query(() => DatabaseEventTriggerDTO) - async findOneDatabaseEventTrigger( - @Args('input') { id }: DatabaseEventTriggerIdInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const { flatDatabaseEventTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatDatabaseEventTriggerMaps'], - }, - ); - - const flatDatabaseEventTrigger = findFlatEntityByIdInFlatEntityMaps({ - flatEntityId: id, - flatEntityMaps: flatDatabaseEventTriggerMaps, - }); - - if (!isDefined(flatDatabaseEventTrigger)) { - throw new DatabaseEventTriggerException( - `Database event trigger with id ${id} not found`, - DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_NOT_FOUND, - ); - } - - return fromFlatDatabaseEventTriggerToDatabaseEventTriggerDto( - flatDatabaseEventTrigger, - ); - } catch (error) { - return databaseEventTriggerGraphQLApiExceptionHandler(error); - } - } - - @Query(() => [DatabaseEventTriggerDTO]) - async findManyDatabaseEventTriggers( - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const { flatDatabaseEventTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatDatabaseEventTriggerMaps'], - }, - ); - - return Object.values(flatDatabaseEventTriggerMaps.byId) - .filter(isDefined) - .map(fromFlatDatabaseEventTriggerToDatabaseEventTriggerDto); - } catch (error) { - return databaseEventTriggerGraphQLApiExceptionHandler(error); - } - } - - @Mutation(() => DatabaseEventTriggerDTO) - async deleteOneDatabaseEventTrigger( - @Args('input') input: DatabaseEventTriggerIdInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const flatDatabaseEventTrigger = - await this.databaseEventTriggerV2Service.destroyOne({ - destroyDatabaseEventTriggerInput: input, - workspaceId, - }); - - return fromFlatDatabaseEventTriggerToDatabaseEventTriggerDto( - flatDatabaseEventTrigger, - ); - } catch (error) { - return databaseEventTriggerGraphQLApiExceptionHandler(error); - } - } - - @Mutation(() => DatabaseEventTriggerDTO) - async updateOneDatabaseEventTrigger( - @Args('input') - input: UpdateDatabaseEventTriggerInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const flatDatabaseEventTrigger = - await this.databaseEventTriggerV2Service.updateOne(input, workspaceId); - - return fromFlatDatabaseEventTriggerToDatabaseEventTriggerDto( - flatDatabaseEventTrigger, - ); - } catch (error) { - return databaseEventTriggerGraphQLApiExceptionHandler(error); - } - } - - @Mutation(() => DatabaseEventTriggerDTO) - async createOneDatabaseEventTrigger( - @Args('input') - input: CreateDatabaseEventTriggerInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const flatDatabaseEventTrigger = - await this.databaseEventTriggerV2Service.createOne(input, workspaceId); - - return fromFlatDatabaseEventTriggerToDatabaseEventTriggerDto( - flatDatabaseEventTrigger, - ); - } catch (error) { - return databaseEventTriggerGraphQLApiExceptionHandler(error); - } - } -} 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 deleted file mode 100644 index 40909c5c8b..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/database-event-trigger-v2.service.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { isDefined } from 'twenty-shared/utils'; - -import { ApplicationService } from 'src/engine/core-modules/application/application.service'; -import { CreateDatabaseEventTriggerInput } from 'src/engine/metadata-modules/database-event-trigger/dtos/create-database-event-trigger.input'; -import { DatabaseEventTriggerIdInput } from 'src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger-id.input'; -import { UpdateDatabaseEventTriggerInput } from 'src/engine/metadata-modules/database-event-trigger/dtos/update-database-event-trigger.input'; -import { - DatabaseEventTriggerException, - DatabaseEventTriggerExceptionCode, -} from 'src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception'; -import { type FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; -import { fromCreateDatabaseEventTriggerInputToFlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/utils/from-create-database-event-trigger-input-to-flat-database-event-trigger.util'; -import { fromUpdateDatabaseEventTriggerInputToFlatDatabaseEventTriggerToUpdateOrThrow } from 'src/engine/metadata-modules/database-event-trigger/utils/from-update-database-event-trigger-input-to-flat-database-event-trigger-to-update-or-throw.util'; -import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util'; -import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception'; -import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service'; - -@Injectable() -export class DatabaseEventTriggerV2Service { - constructor( - private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService, - private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, - private readonly applicationService: ApplicationService, - ) {} - - async createOne( - databaseEventTriggerInput: CreateDatabaseEventTriggerInput, - workspaceId: string, - /** - * @deprecated do not use call validateBuildAndRunWorkspaceMigration contextually - * when interacting with another application than workspace custom one - * */ - applicationId?: string, - ): Promise { - const { workspaceCustomFlatApplication } = - await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow( - { - workspaceId, - }, - ); - - const flatDatabaseEventTriggerToCreate = - fromCreateDatabaseEventTriggerInputToFlatDatabaseEventTrigger({ - createDatabaseEventTriggerInput: databaseEventTriggerInput, - workspaceId, - workspaceCustomApplicationId: - applicationId ?? workspaceCustomFlatApplication.id, - }); - - const validateAndBuildResult = - await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( - { - allFlatEntityOperationByMetadataName: { - databaseEventTrigger: { - flatEntityToCreate: [flatDatabaseEventTriggerToCreate], - flatEntityToDelete: [], - flatEntityToUpdate: [], - }, - }, - workspaceId, - isSystemBuild: false, - }, - ); - - if (isDefined(validateAndBuildResult)) { - throw new WorkspaceMigrationBuilderException( - validateAndBuildResult, - 'Multiple validation errors occurred while creating database event trigger', - ); - } - - const { - flatDatabaseEventTriggerMaps: - recomputedExistingFlatDatabaseEventTriggerMaps, - } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatDatabaseEventTriggerMaps'], - }, - ); - - return findFlatEntityByIdInFlatEntityMapsOrThrow({ - flatEntityId: flatDatabaseEventTriggerToCreate.id, - flatEntityMaps: recomputedExistingFlatDatabaseEventTriggerMaps, - }); - } - - async updateOne( - databaseEventTriggerInput: UpdateDatabaseEventTriggerInput, - workspaceId: string, - ): Promise { - const { flatDatabaseEventTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatDatabaseEventTriggerMaps'], - }, - ); - - const optimisticallyUpdatedFlatDatabaseEventTrigger = - fromUpdateDatabaseEventTriggerInputToFlatDatabaseEventTriggerToUpdateOrThrow( - { - flatDatabaseEventTriggerMaps, - updateDatabaseEventTriggerInput: databaseEventTriggerInput, - }, - ); - - const validateAndBuildResult = - await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( - { - allFlatEntityOperationByMetadataName: { - databaseEventTrigger: { - flatEntityToCreate: [], - flatEntityToDelete: [], - flatEntityToUpdate: [ - optimisticallyUpdatedFlatDatabaseEventTrigger, - ], - }, - }, - workspaceId, - isSystemBuild: false, - }, - ); - - if (isDefined(validateAndBuildResult)) { - throw new WorkspaceMigrationBuilderException( - validateAndBuildResult, - 'Multiple validation errors occurred while updating database event trigger', - ); - } - - const { - flatDatabaseEventTriggerMaps: - recomputedExistingFlatDatabaseEventTriggerMaps, - } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatDatabaseEventTriggerMaps'], - }, - ); - - return findFlatEntityByIdInFlatEntityMapsOrThrow({ - flatEntityId: optimisticallyUpdatedFlatDatabaseEventTrigger.id, - flatEntityMaps: recomputedExistingFlatDatabaseEventTriggerMaps, - }); - } - - async destroyOne({ - destroyDatabaseEventTriggerInput, - workspaceId, - }: { - destroyDatabaseEventTriggerInput: DatabaseEventTriggerIdInput; - workspaceId: string; - }): Promise { - const { flatDatabaseEventTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatDatabaseEventTriggerMaps'], - }, - ); - - const existingFlatDatabaseEventTrigger = - flatDatabaseEventTriggerMaps.byId[destroyDatabaseEventTriggerInput.id]; - - if (!isDefined(existingFlatDatabaseEventTrigger)) { - throw new DatabaseEventTriggerException( - 'Database event trigger to destroy not found', - DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_NOT_FOUND, - ); - } - - const validateAndBuildResult = - await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( - { - allFlatEntityOperationByMetadataName: { - databaseEventTrigger: { - flatEntityToCreate: [], - flatEntityToDelete: [existingFlatDatabaseEventTrigger], - flatEntityToUpdate: [], - }, - }, - workspaceId, - isSystemBuild: false, - }, - ); - - if (isDefined(validateAndBuildResult)) { - throw new WorkspaceMigrationBuilderException( - validateAndBuildResult, - 'Multiple validation errors occurred while destroying database event trigger', - ); - } - - return existingFlatDatabaseEventTrigger; - } -} diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/workspace-flat-database-event-trigger-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/workspace-flat-database-event-trigger-map-cache.service.ts deleted file mode 100644 index d2db7b8b39..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/services/workspace-flat-database-event-trigger-map-cache.service.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; - -import { removePropertiesFromRecord } from 'twenty-shared/utils'; -import { Repository } from 'typeorm'; - -import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service'; - -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; -import { FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; -import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant'; -import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { getMetadataEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-entity-relation-properties.util'; -import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator'; -import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util'; - -@Injectable() -@WorkspaceCache('flatDatabaseEventTriggerMaps') -export class WorkspaceFlatDatabaseEventTriggerMapCacheService extends WorkspaceCacheProvider< - FlatEntityMaps -> { - constructor( - @InjectRepository(DatabaseEventTriggerEntity) - private readonly databaseEventTriggerRepository: Repository, - ) { - super(); - } - - async computeForCache( - workspaceId: string, - ): Promise> { - const databaseEventTriggers = - await this.databaseEventTriggerRepository.find({ - where: { - workspaceId, - }, - }); - - const flatDatabaseEventTriggerMaps = createEmptyFlatEntityMaps(); - - for (const databaseEventTriggerEntity of databaseEventTriggers) { - const flatDatabaseEventTrigger = { - ...removePropertiesFromRecord( - databaseEventTriggerEntity, - getMetadataEntityRelationProperties('databaseEventTrigger'), - ), - universalIdentifier: databaseEventTriggerEntity.universalIdentifier, - createdAt: databaseEventTriggerEntity.createdAt.toISOString(), - updatedAt: databaseEventTriggerEntity.updatedAt.toISOString(), - } satisfies FlatDatabaseEventTrigger; - - addFlatEntityToFlatEntityMapsThroughMutationOrThrow({ - flatEntity: flatDatabaseEventTrigger, - flatEntityMapsToMutate: flatDatabaseEventTriggerMaps, - }); - } - - return flatDatabaseEventTriggerMaps; - } -} diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type.ts deleted file mode 100644 index 9ff8d04d5a..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { type DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; - -export type FlatDatabaseEventTrigger = - FlatEntityFrom; diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/__tests__/transform-event-batch-to-event-payloads.spec.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/__tests__/transform-event-batch-to-event-payloads.spec.ts index 1500510424..ff989bd3cf 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/__tests__/transform-event-batch-to-event-payloads.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/__tests__/transform-event-batch-to-event-payloads.spec.ts @@ -1,24 +1,21 @@ import type { ObjectRecordEvent } from 'twenty-shared/database-events'; -import { type DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; import { transformEventBatchToEventPayloads } from 'src/engine/metadata-modules/database-event-trigger/utils/transform-event-batch-to-event-payloads'; import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock'; +import { type ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; import type { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event-batch.type'; -const createMockDatabaseEventListener = ( - overrides: Partial = {}, -): DatabaseEventTriggerEntity => +const createMockServerlessFunction = ( + overrides: Partial = {}, +): ServerlessFunctionEntity => ({ - id: 'listener-1', + id: 'function-1', workspaceId: 'workspace-1', - settings: { + databaseEventTriggerSettings: { eventName: 'company.updated', }, - serverlessFunction: { - id: 'function-1', - }, ...overrides, - }) as DatabaseEventTriggerEntity; + }) as ServerlessFunctionEntity; const createMockEvent = ( overrides: Partial = {}, @@ -46,13 +43,13 @@ const createMockWorkspaceEventBatch = ( describe('transformEventBatchToEventPayloads', () => { describe('basic transformation', () => { - it('should transform a single event batch with a single listener', () => { + it('should transform a single event batch with a single serverless function', () => { const workspaceEventBatch = createMockWorkspaceEventBatch(); - const databaseEventListeners = [createMockDatabaseEventListener()]; + const serverlessFunctions = [createMockServerlessFunction()]; const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }); expect(result).toHaveLength(1); @@ -75,11 +72,11 @@ describe('transformEventBatchToEventPayloads', () => { createMockEvent({ recordId: 'record-3' }), ], }); - const databaseEventListeners = [createMockDatabaseEventListener()]; + const serverlessFunctions = [createMockServerlessFunction()]; const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }); expect(result).toHaveLength(3); @@ -88,22 +85,20 @@ describe('transformEventBatchToEventPayloads', () => { ).toEqual(['record-1', 'record-2', 'record-3']); }); - it('should create payloads for each listener', () => { + it('should create payloads for each serverless function', () => { const workspaceEventBatch = createMockWorkspaceEventBatch(); - const databaseEventListeners = [ - createMockDatabaseEventListener({ - id: 'listener-1', - serverlessFunction: { id: 'function-1' }, - } as Partial), - createMockDatabaseEventListener({ - id: 'listener-2', - serverlessFunction: { id: 'function-2' }, - } as Partial), + const serverlessFunctions = [ + createMockServerlessFunction({ + id: 'function-1', + }), + createMockServerlessFunction({ + id: 'function-2', + }), ]; const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }); expect(result).toHaveLength(2); @@ -129,15 +124,15 @@ describe('transformEventBatchToEventPayloads', () => { }), ], }); - const databaseEventListeners = [ - createMockDatabaseEventListener({ - settings: { eventName: 'company.updated' }, + const serverlessFunctions = [ + createMockServerlessFunction({ + databaseEventTriggerSettings: { eventName: 'company.updated' }, }), ]; const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }); expect(result).toHaveLength(2); @@ -157,15 +152,18 @@ describe('transformEventBatchToEventPayloads', () => { }), ], }); - const databaseEventListeners = [ - createMockDatabaseEventListener({ - settings: { eventName: 'company.updated', updatedFields: [] }, + const serverlessFunctions = [ + createMockServerlessFunction({ + databaseEventTriggerSettings: { + eventName: 'company.updated', + updatedFields: [], + }, }), ]; const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }); expect(result).toHaveLength(2); @@ -189,15 +187,18 @@ describe('transformEventBatchToEventPayloads', () => { }), ], }); - const databaseEventListeners = [ - createMockDatabaseEventListener({ - settings: { eventName: 'company.updated', updatedFields: ['name'] }, + const serverlessFunctions = [ + createMockServerlessFunction({ + databaseEventTriggerSettings: { + eventName: 'company.updated', + updatedFields: ['name'], + }, }), ]; const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }); expect(result).toHaveLength(2); @@ -224,9 +225,9 @@ describe('transformEventBatchToEventPayloads', () => { }), ], }); - const databaseEventListeners = [ - createMockDatabaseEventListener({ - settings: { + const serverlessFunctions = [ + createMockServerlessFunction({ + databaseEventTriggerSettings: { eventName: 'company.updated', updatedFields: ['name', 'address'], }, @@ -235,7 +236,7 @@ describe('transformEventBatchToEventPayloads', () => { const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }); expect(result).toHaveLength(2); @@ -258,21 +259,24 @@ describe('transformEventBatchToEventPayloads', () => { }), ], }); - const databaseEventListeners = [ - createMockDatabaseEventListener({ - settings: { eventName: 'company.updated', updatedFields: ['phone'] }, + const serverlessFunctions = [ + createMockServerlessFunction({ + databaseEventTriggerSettings: { + eventName: 'company.updated', + updatedFields: ['phone'], + }, }), ]; const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }); expect(result).toHaveLength(0); }); - it('should handle different updatedFields filters per listener', () => { + it('should handle different updatedFields filters per serverless function', () => { const workspaceEventBatch = createMockWorkspaceEventBatch({ name: 'company.updated', events: [ @@ -286,25 +290,26 @@ describe('transformEventBatchToEventPayloads', () => { }), ], }); - const databaseEventListeners = [ - createMockDatabaseEventListener({ - id: 'listener-1', - settings: { eventName: 'company.updated', updatedFields: ['name'] }, - serverlessFunction: { id: 'function-1' }, - } as Partial), - createMockDatabaseEventListener({ - id: 'listener-2', - settings: { + const serverlessFunctions = [ + createMockServerlessFunction({ + id: 'function-1', + databaseEventTriggerSettings: { + eventName: 'company.updated', + updatedFields: ['name'], + }, + }), + createMockServerlessFunction({ + id: 'function-2', + databaseEventTriggerSettings: { eventName: 'company.updated', updatedFields: ['address'], }, - serverlessFunction: { id: 'function-2' }, - } as Partial), + }), ]; const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }); expect(result).toHaveLength(2); @@ -329,12 +334,12 @@ describe('transformEventBatchToEventPayloads', () => { }); describe('edge cases', () => { - it('should return empty array when no listeners provided', () => { + it('should return empty array when no serverless functions provided', () => { const workspaceEventBatch = createMockWorkspaceEventBatch(); const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners: [], + serverlessFunctions: [], }); expect(result).toHaveLength(0); @@ -344,11 +349,11 @@ describe('transformEventBatchToEventPayloads', () => { const workspaceEventBatch = createMockWorkspaceEventBatch({ events: [], }); - const databaseEventListeners = [createMockDatabaseEventListener()]; + const serverlessFunctions = [createMockServerlessFunction()]; const result = transformEventBatchToEventPayloads({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }); expect(result).toHaveLength(0); diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/database-event-trigger-graphql-api-exception-handler.utils.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/database-event-trigger-graphql-api-exception-handler.utils.ts deleted file mode 100644 index e7d7408c3a..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/database-event-trigger-graphql-api-exception-handler.utils.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - ConflictError, - NotFoundError, -} from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; -import { - DatabaseEventTriggerException, - DatabaseEventTriggerExceptionCode, -} from 'src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception'; - -export const databaseEventTriggerGraphQLApiExceptionHandler = ( - error: Error, -): never => { - if (error instanceof DatabaseEventTriggerException) { - switch (error.code) { - case DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_NOT_FOUND: - throw new NotFoundError('Database event trigger not found'); - case DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_ALREADY_EXIST: - throw new ConflictError('Database event trigger already exists'); - default: - throw error; - } - } - - throw error; -}; diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-create-database-event-trigger-input-to-flat-database-event-trigger.util.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-create-database-event-trigger-input-to-flat-database-event-trigger.util.ts deleted file mode 100644 index 88b06f4a5f..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-create-database-event-trigger-input-to-flat-database-event-trigger.util.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { v4 as uuidV4 } from 'uuid'; - -import { type CreateDatabaseEventTriggerInput } from 'src/engine/metadata-modules/database-event-trigger/dtos/create-database-event-trigger.input'; -import { type FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; - -export const fromCreateDatabaseEventTriggerInputToFlatDatabaseEventTrigger = ({ - createDatabaseEventTriggerInput, - workspaceId, - workspaceCustomApplicationId, -}: { - createDatabaseEventTriggerInput: CreateDatabaseEventTriggerInput; - workspaceId: string; - workspaceCustomApplicationId: string; -}): FlatDatabaseEventTrigger => { - const now = new Date().toISOString(); - const id = uuidV4(); - - return { - id, - universalIdentifier: - createDatabaseEventTriggerInput.universalIdentifier ?? uuidV4(), - settings: createDatabaseEventTriggerInput.settings, - serverlessFunctionId: createDatabaseEventTriggerInput.serverlessFunctionId, - workspaceId, - createdAt: now, - updatedAt: now, - applicationId: workspaceCustomApplicationId, - }; -}; diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-flat-database-event-trigger-to-database-event-trigger-dto.util.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-flat-database-event-trigger-to-database-event-trigger-dto.util.ts deleted file mode 100644 index 446e18037b..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/from-flat-database-event-trigger-to-database-event-trigger-dto.util.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { type DatabaseEventTriggerDTO } from 'src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger.dto'; -import { type FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; - -export const fromFlatDatabaseEventTriggerToDatabaseEventTriggerDto = ( - flatDatabaseEventTrigger: FlatDatabaseEventTrigger, -): DatabaseEventTriggerDTO => ({ - id: flatDatabaseEventTrigger.id, - settings: flatDatabaseEventTrigger.settings, - createdAt: new Date(flatDatabaseEventTrigger.createdAt), - updatedAt: new Date(flatDatabaseEventTrigger.updatedAt), -}); 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 deleted file mode 100644 index 0b4ec729e9..0000000000 --- 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 +++ /dev/null @@ -1,32 +0,0 @@ -import { type UpdateDatabaseEventTriggerInput } from 'src/engine/metadata-modules/database-event-trigger/dtos/update-database-event-trigger.input'; -import { - DatabaseEventTriggerException, - DatabaseEventTriggerExceptionCode, -} from 'src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception'; -import { type FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; -import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; - -export const fromUpdateDatabaseEventTriggerInputToFlatDatabaseEventTriggerToUpdateOrThrow = - ({ - flatDatabaseEventTriggerMaps, - updateDatabaseEventTriggerInput, - }: { - flatDatabaseEventTriggerMaps: FlatEntityMaps; - updateDatabaseEventTriggerInput: UpdateDatabaseEventTriggerInput; - }): FlatDatabaseEventTrigger => { - const existingFlatDatabaseEventTrigger = - flatDatabaseEventTriggerMaps.byId[updateDatabaseEventTriggerInput.id]; - - if (!existingFlatDatabaseEventTrigger) { - throw new DatabaseEventTriggerException( - 'Database event trigger not found', - DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_NOT_FOUND, - ); - } - - return { - ...existingFlatDatabaseEventTrigger, - settings: updateDatabaseEventTriggerInput.update.settings, - updatedAt: new Date().toISOString(), - }; - }; diff --git a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/transform-event-batch-to-event-payloads.ts b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/transform-event-batch-to-event-payloads.ts index 863be1b1fd..c5e748b53d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/transform-event-batch-to-event-payloads.ts +++ b/packages/twenty-server/src/engine/metadata-modules/database-event-trigger/utils/transform-event-batch-to-event-payloads.ts @@ -5,23 +5,24 @@ import type { ObjectRecordEvent, } from 'twenty-shared/database-events'; -import { type DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; import { type ServerlessFunctionTriggerJobData } from 'src/engine/metadata-modules/serverless-function/jobs/serverless-function-trigger.job'; +import { type ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; import type { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event-batch.type'; export const transformEventBatchToEventPayloads = ({ workspaceEventBatch, - databaseEventListeners, + serverlessFunctions, }: { workspaceEventBatch: WorkspaceEventBatch; - databaseEventListeners: DatabaseEventTriggerEntity[]; + serverlessFunctions: ServerlessFunctionEntity[]; }): ServerlessFunctionTriggerJobData[] => { const result: ServerlessFunctionTriggerJobData[] = []; const { events, ...batchEventInfo } = workspaceEventBatch; const [, operation] = workspaceEventBatch.name.split('.'); - for (const databaseEventListener of databaseEventListeners) { - const triggerUpdatedFields = databaseEventListener.settings.updatedFields; + for (const serverlessFunction of serverlessFunctions) { + const triggerUpdatedFields = + serverlessFunction.databaseEventTriggerSettings?.updatedFields; const filteredEvents = filterEventsByUpdatedFields({ events, @@ -33,8 +34,8 @@ export const transformEventBatchToEventPayloads = ({ const payload: DatabaseEventPayload = { ...batchEventInfo, ...event }; result.push({ - serverlessFunctionId: databaseEventListener.serverlessFunction.id, - workspaceId: databaseEventListener.workspaceId, + serverlessFunctionId: serverlessFunction.id, + workspaceId: serverlessFunction.workspaceId, payload, }); } diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-flat-entity-properties-to-compare-and-stringify.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-flat-entity-properties-to-compare-and-stringify.constant.ts index 6da91d20c0..79e2d85975 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-flat-entity-properties-to-compare-and-stringify.constant.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-flat-entity-properties-to-compare-and-stringify.constant.ts @@ -1,7 +1,5 @@ import { type AllMetadataName } from 'twenty-shared/metadata'; -import { FLAT_CRON_TRIGGER_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/cron-trigger/constants/flat-cron-trigger-editable-properties.constant'; -import { FLAT_DATABASE_EVENT_TRIGGER_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/database-event-trigger/constants/flat-database-event-trigger-editable-properties.constant'; import { FLAT_AGENT_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-agent/constants/flat-agent-editable-properties.constant'; import { FLAT_COMMAND_MENU_ITEM_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-command-menu-item/constants/flat-command-menu-item-editable-properties.constant'; import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type'; @@ -22,7 +20,6 @@ import { FLAT_VIEW_FILTER_GROUP_EDITABLE_PROPERTIES } from 'src/engine/metadata- import { FLAT_VIEW_FILTER_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-view-filter/constants/flat-view-filter-editable-properties.constant'; import { FLAT_VIEW_GROUP_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-view-group/constants/flat-view-group-editable-properties.constant'; import { FLAT_VIEW_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-view/constants/flat-view-editable-properties.constant'; -import { FLAT_ROUTE_TRIGGER_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-editable-properties.constant'; import { FLAT_SERVERLESS_FUNCTION_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/serverless-function/constants/flat-serverless-function-editable-properties.constant'; type OneFlatEntityConfiguration = { @@ -88,15 +85,15 @@ export const ALL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY = { propertiesToStringify: ['toolInputSchema', 'publishedVersions'], }, cronTrigger: { - propertiesToCompare: [...FLAT_CRON_TRIGGER_EDITABLE_PROPERTIES], - propertiesToStringify: ['settings'], + propertiesToCompare: [], + propertiesToStringify: [], }, databaseEventTrigger: { - propertiesToCompare: [...FLAT_DATABASE_EVENT_TRIGGER_EDITABLE_PROPERTIES], - propertiesToStringify: ['settings'], + propertiesToCompare: [], + propertiesToStringify: [], }, routeTrigger: { - propertiesToCompare: [...FLAT_ROUTE_TRIGGER_EDITABLE_PROPERTIES], + propertiesToCompare: [], propertiesToStringify: [], }, viewFilter: { diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-entity-by-metadata-name.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-entity-by-metadata-name.constant.ts index 52ca92405d..e6d9465d0e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-entity-by-metadata-name.constant.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-entity-by-metadata-name.constant.ts @@ -3,8 +3,6 @@ import { type EntityTarget, type ObjectLiteral } from 'typeorm'; import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity'; import { CommandMenuItemEntity } from 'src/engine/metadata-modules/command-menu-item/entities/command-menu-item.entity'; -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { FrontComponentEntity } from 'src/engine/metadata-modules/front-component/entities/front-component.entity'; import { IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity'; @@ -16,7 +14,6 @@ import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout- import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity'; import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity'; import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity'; -import { RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { RowLevelPermissionPredicateGroupEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate-group.entity'; import { RowLevelPermissionPredicateEntity } from 'src/engine/metadata-modules/row-level-permission-predicate/entities/row-level-permission-predicate.entity'; import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; @@ -39,9 +36,9 @@ export const ALL_METADATA_ENTITY_BY_METADATA_NAME = { view: ViewEntity, index: IndexMetadataEntity, pageLayoutTab: PageLayoutTabEntity, - routeTrigger: RouteTriggerEntity, - cronTrigger: CronTriggerEntity, - databaseEventTrigger: DatabaseEventTriggerEntity, + routeTrigger: ServerlessFunctionEntity, + cronTrigger: ServerlessFunctionEntity, + databaseEventTrigger: ServerlessFunctionEntity, frontComponent: FrontComponentEntity, fieldMetadata: FieldMetadataEntity, pageLayout: PageLayoutEntity, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-relations.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-relations.constant.ts index 110563283c..0b015dde1d 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-relations.constant.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-metadata-relations.constant.ts @@ -267,45 +267,29 @@ export const ALL_METADATA_RELATIONS = { application: null, serverlessFunctionLayer: null, }, - oneToMany: { - cronTriggers: { metadataName: 'cronTrigger' }, - databaseEventTriggers: { metadataName: 'databaseEventTrigger' }, - routeTriggers: { metadataName: 'routeTrigger' }, - }, + oneToMany: {}, }, cronTrigger: { manyToOne: { - serverlessFunction: { - metadataName: 'serverlessFunction', - flatEntityForeignKeyAggregator: 'cronTriggerIds', - foreignKey: 'serverlessFunctionId', - }, - workspace: null, application: null, + serverlessFunctionLayer: null, + workspace: null, }, oneToMany: {}, }, databaseEventTrigger: { manyToOne: { - serverlessFunction: { - metadataName: 'serverlessFunction', - flatEntityForeignKeyAggregator: 'databaseEventTriggerIds', - foreignKey: 'serverlessFunctionId', - }, - workspace: null, application: null, + serverlessFunctionLayer: null, + workspace: null, }, oneToMany: {}, }, routeTrigger: { manyToOne: { - serverlessFunction: { - metadataName: 'serverlessFunction', - flatEntityForeignKeyAggregator: 'routeTriggerIds', - foreignKey: 'serverlessFunctionId', - }, - workspace: null, application: null, + serverlessFunctionLayer: null, + workspace: null, }, oneToMany: {}, }, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name.ts index a1787927ee..493aacdd15 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/types/all-flat-entity-types-by-metadata-name.ts @@ -1,5 +1,3 @@ -import { type FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; -import { type FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; import { type FlatAgent } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type'; import { type FlatCommandMenuItem } from 'src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type'; import { type MetadataEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-entity.type'; @@ -21,7 +19,6 @@ import { type FlatViewFilter } from 'src/engine/metadata-modules/flat-view-filte import { type FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type'; import { type FlatView } from 'src/engine/metadata-modules/flat-view/types/flat-view.type'; import { type NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation-menu-item/entities/navigation-menu-item.entity'; -import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; import { type FlatRowLevelPermissionPredicateGroup } from 'src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate-group.type'; import { type FlatRowLevelPermissionPredicate } from 'src/engine/metadata-modules/row-level-permission-predicate/types/flat-row-level-permission-predicate.type'; import { type FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type'; @@ -35,16 +32,6 @@ import { type DeleteCommandMenuItemAction, type UpdateCommandMenuItemAction, } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/types/workspace-migration-command-menu-item-action.type'; -import { - type CreateCronTriggerAction, - type DeleteCronTriggerAction, - type UpdateCronTriggerAction, -} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/types/workspace-migration-cron-trigger-action.type'; -import { - type CreateDatabaseEventTriggerAction, - type DeleteDatabaseEventTriggerAction, - type UpdateDatabaseEventTriggerAction, -} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/types/workspace-migration-database-event-trigger-action.type'; import { type CreateFieldAction, type DeleteFieldAction, @@ -95,11 +82,6 @@ import { type DeleteRoleAction, type UpdateRoleAction, } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role/types/workspace-migration-role-action.type'; -import { - type CreateRouteTriggerAction, - type DeleteRouteTriggerAction, - type UpdateRouteTriggerAction, -} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/types/workspace-migration-route-trigger-action.type'; import { type CreateRowLevelPermissionPredicateGroupAction, type DeleteRowLevelPermissionPredicateGroupAction, @@ -244,30 +226,30 @@ export type AllFlatEntityTypesByMetadataName = { }; cronTrigger: { actions: { - create: CreateCronTriggerAction; - update: UpdateCronTriggerAction; - delete: DeleteCronTriggerAction; + create: never; + update: never; + delete: never; }; - flatEntity: FlatCronTrigger; - entity: MetadataEntity<'cronTrigger'>; + flatEntity: FlatServerlessFunction; + entity: MetadataEntity<'serverlessFunction'>; }; databaseEventTrigger: { actions: { - create: CreateDatabaseEventTriggerAction; - update: UpdateDatabaseEventTriggerAction; - delete: DeleteDatabaseEventTriggerAction; + create: never; + update: never; + delete: never; }; - flatEntity: FlatDatabaseEventTrigger; - entity: MetadataEntity<'databaseEventTrigger'>; + flatEntity: FlatServerlessFunction; + entity: MetadataEntity<'serverlessFunction'>; }; routeTrigger: { actions: { - create: CreateRouteTriggerAction; - update: UpdateRouteTriggerAction; - delete: DeleteRouteTriggerAction; + create: never; + update: never; + delete: never; }; - flatEntity: FlatRouteTrigger; - entity: MetadataEntity<'routeTrigger'>; + flatEntity: FlatServerlessFunction; + entity: MetadataEntity<'serverlessFunction'>; }; viewFilter: { actions: { diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/__snapshots__/get-metadata-related-metadata-names.util.spec.ts.snap b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/__snapshots__/get-metadata-related-metadata-names.util.spec.ts.snap index e5e03c8b6c..e4b06924dc 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/__snapshots__/get-metadata-related-metadata-names.util.spec.ts.snap +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/__snapshots__/get-metadata-related-metadata-names.util.spec.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`getMetadataRelatedMetadataNames should return related metadata names for agent 1`] = `[]`; @@ -8,17 +8,9 @@ exports[`getMetadataRelatedMetadataNames should return related metadata names fo ] `; -exports[`getMetadataRelatedMetadataNames should return related metadata names for cronTrigger 1`] = ` -[ - "serverlessFunction", -] -`; +exports[`getMetadataRelatedMetadataNames should return related metadata names for cronTrigger 1`] = `[]`; -exports[`getMetadataRelatedMetadataNames should return related metadata names for databaseEventTrigger 1`] = ` -[ - "serverlessFunction", -] -`; +exports[`getMetadataRelatedMetadataNames should return related metadata names for databaseEventTrigger 1`] = `[]`; exports[`getMetadataRelatedMetadataNames should return related metadata names for fieldMetadata 1`] = ` [ @@ -89,11 +81,7 @@ exports[`getMetadataRelatedMetadataNames should return related metadata names fo ] `; -exports[`getMetadataRelatedMetadataNames should return related metadata names for routeTrigger 1`] = ` -[ - "serverlessFunction", -] -`; +exports[`getMetadataRelatedMetadataNames should return related metadata names for routeTrigger 1`] = `[]`; exports[`getMetadataRelatedMetadataNames should return related metadata names for rowLevelPermissionPredicate 1`] = ` [ @@ -113,13 +101,7 @@ exports[`getMetadataRelatedMetadataNames should return related metadata names fo ] `; -exports[`getMetadataRelatedMetadataNames should return related metadata names for serverlessFunction 1`] = ` -[ - "cronTrigger", - "databaseEventTrigger", - "routeTrigger", -] -`; +exports[`getMetadataRelatedMetadataNames should return related metadata names for serverlessFunction 1`] = `[]`; exports[`getMetadataRelatedMetadataNames should return related metadata names for skill 1`] = `[]`; diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/__snapshots__/sort-metadata-names-children-first.util.spec.ts.snap b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/__snapshots__/sort-metadata-names-children-first.util.spec.ts.snap index 9258fe6651..46fcfaf815 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/__snapshots__/sort-metadata-names-children-first.util.spec.ts.snap +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/utils/__tests__/__snapshots__/sort-metadata-names-children-first.util.spec.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`sortMetadataNamesChildrenFirst should return metadata names sorted with children first (most manyToOne relations first) 1`] = ` [ @@ -8,24 +8,24 @@ exports[`sortMetadataNamesChildrenFirst should return metadata names sorted with "pageLayoutWidget", "viewField", "commandMenuItem", - "cronTrigger", - "databaseEventTrigger", "index", "roleTarget", - "routeTrigger", "rowLevelPermissionPredicateGroup", "viewGroup", "agent", + "cronTrigger", + "databaseEventTrigger", "frontComponent", "pageLayout", "pageLayoutTab", + "routeTrigger", + "serverlessFunction", "skill", "view", "viewFilterGroup", "webhook", "fieldMetadata", "role", - "serverlessFunction", "objectMetadata", ] `; 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 f9127cd6ec..3042956852 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 @@ -5,9 +5,7 @@ import { AiAgentModule } from 'src/engine/metadata-modules/ai/ai-agent/ai-agent. import { AiChatModule } from 'src/engine/metadata-modules/ai/ai-chat/ai-chat.module'; import { CommandMenuItemModule } from 'src/engine/metadata-modules/command-menu-item/command-menu-item.module'; import { NavigationMenuItemModule } from 'src/engine/metadata-modules/navigation-menu-item/navigation-menu-item.module'; -import { CronTriggerModule } from 'src/engine/metadata-modules/cron-trigger/cron-trigger.module'; import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; -import { DatabaseEventTriggerModule } from 'src/engine/metadata-modules/database-event-trigger/database-event-trigger.module'; import { FieldMetadataModule } from 'src/engine/metadata-modules/field-metadata/field-metadata.module'; import { FrontComponentModule } from 'src/engine/metadata-modules/front-component/front-component.module'; import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; @@ -42,8 +40,6 @@ import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/work RoleModule, PermissionsModule, RouteTriggerModule, - CronTriggerModule, - DatabaseEventTriggerModule, WebhookModule, ], providers: [], 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 deleted file mode 100644 index d4cc4854fc..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/constants/flat-route-trigger-editable-properties.constant.ts +++ /dev/null @@ -1,8 +0,0 @@ -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', - 'forwardedRequestHeaders', -] 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 deleted file mode 100644 index 9977d3af41..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Field, HideField, InputType } from '@nestjs/graphql'; - -import { - IsArray, - IsBoolean, - IsEnum, - IsNotEmpty, - IsOptional, - IsString, - IsUUID, -} from 'class-validator'; -import { HTTPMethod } from 'twenty-shared/types'; - -@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; - - @IsArray() - @IsString({ each: true }) - @IsOptional() - @Field(() => [String], { - defaultValue: [], - description: - 'List of HTTP header names to forward to the serverless function event', - }) - forwardedRequestHeaders: string[]; - - @HideField() - universalIdentifier?: string; - - @HideField() - applicationId?: 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 deleted file mode 100644 index b17e2d03e1..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger-id.input.ts +++ /dev/null @@ -1,11 +0,0 @@ -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 deleted file mode 100644 index a760007b1f..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Field, ID, ObjectType, registerEnumType } from '@nestjs/graphql'; - -import { HTTPMethod } from 'twenty-shared/types'; - -registerEnumType(HTTPMethod, { name: 'HTTPMethod' }); - -@ObjectType('RouteTrigger') -export class RouteTriggerDTO { - @Field(() => ID) - id: string; - - @Field() - path: string; - - @Field() - isAuthRequired: boolean; - - @Field(() => HTTPMethod) - httpMethod: HTTPMethod; - - @Field(() => [String], { - description: - 'List of HTTP header names to forward to the serverless function event', - }) - forwardedRequestHeaders: 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 deleted file mode 100644 index e57a64da22..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/dtos/update-route-trigger.input.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Field, InputType } from '@nestjs/graphql'; - -import { Type } from 'class-transformer'; -import { - IsArray, - IsBoolean, - IsEnum, - IsNotEmpty, - IsOptional, - IsString, - IsUUID, - ValidateNested, -} from 'class-validator'; -import { HTTPMethod } from 'twenty-shared/types'; - -@InputType() -class UpdateRouteTriggerInputUpdates { - @IsString() - @IsNotEmpty() - @Field() - path: string; - - @IsBoolean() - @IsNotEmpty() - @Field() - isAuthRequired: boolean; - - @IsEnum(HTTPMethod) - @IsNotEmpty() - @Field(() => HTTPMethod) - httpMethod: HTTPMethod; - - @IsArray() - @IsString({ each: true }) - @IsOptional() - @Field(() => [String], { - defaultValue: [], - description: - 'List of HTTP header names to forward to the serverless function event', - }) - forwardedRequestHeaders: string[]; -} - -@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/resolvers/route-trigger.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts deleted file mode 100644 index 7868f77ca2..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/resolvers/route-trigger.resolver.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; -import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; - -import { PermissionFlagType } from 'twenty-shared/constants'; -import { isDefined } from 'twenty-shared/utils'; - -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 { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; -import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; -import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; -import { PermissionsGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/permissions/utils/permissions-graphql-api-exception.filter'; -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 { - RouteTriggerException, - RouteTriggerExceptionCode, -} from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception'; -import { RouteTriggerV2Service } from 'src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service'; -import { fromFlatRouteTriggerToRouteTriggerDto } from 'src/engine/metadata-modules/route-trigger/utils/from-flat-route-trigger-to-route-trigger-dto.util'; -import { routeTriggerGraphQLApiExceptionHandler } from 'src/engine/metadata-modules/route-trigger/utils/route-trigger-graphql-api-exception-handler.utils'; - -@UseGuards( - WorkspaceAuthGuard, - SettingsPermissionGuard(PermissionFlagType.WORKFLOWS), -) -@Resolver() -@UsePipes(ResolverValidationPipe) -@UseFilters( - PreventNestToAutoLogGraphqlErrorsFilter, - PermissionsGraphqlApiExceptionFilter, -) -export class RouteTriggerResolver { - constructor( - private readonly routeV2Service: RouteTriggerV2Service, - private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService, - ) {} - - @Query(() => RouteTriggerDTO) - async findOneRouteTrigger( - @Args('input') { id }: RouteTriggerIdInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const { flatRouteTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatRouteTriggerMaps'], - }, - ); - - const flatRouteTrigger = findFlatEntityByIdInFlatEntityMaps({ - flatEntityId: id, - flatEntityMaps: flatRouteTriggerMaps, - }); - - if (!isDefined(flatRouteTrigger)) { - throw new RouteTriggerException( - `Route trigger with id ${id} not found`, - RouteTriggerExceptionCode.ROUTE_NOT_FOUND, - ); - } - - return fromFlatRouteTriggerToRouteTriggerDto(flatRouteTrigger); - } catch (error) { - return routeTriggerGraphQLApiExceptionHandler(error); - } - } - - @Query(() => [RouteTriggerDTO]) - async findManyRouteTriggers( - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const { flatRouteTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatRouteTriggerMaps'], - }, - ); - - return Object.values(flatRouteTriggerMaps.byId) - .filter(isDefined) - .map(fromFlatRouteTriggerToRouteTriggerDto); - } catch (error) { - return routeTriggerGraphQLApiExceptionHandler(error); - } - } - - @Mutation(() => RouteTriggerDTO) - async deleteOneRouteTrigger( - @Args('input') input: RouteTriggerIdInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const flatRouteTrigger = await this.routeV2Service.destroyOne({ - destroyRouteTriggerInput: input, - workspaceId, - }); - - return fromFlatRouteTriggerToRouteTriggerDto(flatRouteTrigger); - } catch (error) { - return routeTriggerGraphQLApiExceptionHandler(error); - } - } - - @Mutation(() => RouteTriggerDTO) - async updateOneRouteTrigger( - @Args('input') - input: UpdateRouteTriggerInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const flatRouteTrigger = await this.routeV2Service.updateOne( - input, - workspaceId, - ); - - return fromFlatRouteTriggerToRouteTriggerDto(flatRouteTrigger); - } catch (error) { - return routeTriggerGraphQLApiExceptionHandler(error); - } - } - - @Mutation(() => RouteTriggerDTO) - async createOneRouteTrigger( - @Args('input') - input: CreateRouteTriggerInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ): Promise { - try { - const flatRouteTrigger = await this.routeV2Service.createOne( - input, - workspaceId, - ); - - return fromFlatRouteTriggerToRouteTriggerDto(flatRouteTrigger); - } catch (error) { - return routeTriggerGraphQLApiExceptionHandler(error); - } - } -} diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts deleted file mode 100644 index 724c470d22..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.entity.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { HTTPMethod } from 'twenty-shared/types'; -import { - Column, - CreateDateColumn, - Entity, - Index, - JoinColumn, - ManyToOne, - PrimaryGeneratedColumn, - Relation, - Unique, - UpdateDateColumn, -} from 'typeorm'; - -import { type JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type'; -import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; -import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface'; - -@Entity({ name: 'routeTrigger', schema: 'core' }) -@Unique('IDX_ROUTE_TRIGGER_PATH_HTTP_METHOD_WORKSPACE_ID_UNIQUE', [ - 'path', - 'httpMethod', - 'workspaceId', -]) -@Index('IDX_ROUTE_TRIGGER_SERVERLESS_FUNCTION_ID', ['serverlessFunctionId']) -export class RouteTriggerEntity - extends SyncableEntity - implements Required -{ - @PrimaryGeneratedColumn('uuid') - id: string; - - @Column({ nullable: false }) - path: string; - - @Column({ nullable: false, default: true }) - isAuthRequired: boolean; - - @Column({ - type: 'enum', - enum: HTTPMethod, - default: HTTPMethod.GET, - nullable: false, - }) - httpMethod: HTTPMethod; - - @Column({ nullable: false, type: 'jsonb', default: [] }) - forwardedRequestHeaders: JsonbProperty; - - @ManyToOne( - () => ServerlessFunctionEntity, - (serverlessFunction) => serverlessFunction.routeTriggers, - { onDelete: 'CASCADE' }, - ) - @JoinColumn({ name: 'serverlessFunctionId' }) - serverlessFunction: Relation; - - @Column({ nullable: false, type: 'uuid' }) - serverlessFunctionId: string; - - @CreateDateColumn({ type: 'timestamptz' }) - createdAt: Date; - - @UpdateDateColumn({ type: 'timestamptz' }) - updatedAt: Date; -} 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 index b6a3efd29e..e9eb5d1802 100644 --- 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 @@ -1,38 +1,22 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { TokenModule } from 'src/engine/core-modules/auth/token/token.module'; import { WorkspaceDomainsModule } from 'src/engine/core-modules/domain/workspace-domains/workspace-domains.module'; -import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module'; -import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.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 { RouteTriggerEntity } 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 { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module'; -import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module'; @Module({ imports: [ - TypeOrmModule.forFeature([RouteTriggerEntity]), - ApplicationModule, + TypeOrmModule.forFeature([ServerlessFunctionEntity]), TokenModule, WorkspaceDomainsModule, ServerlessFunctionModule, - WorkspaceManyOrAllFlatEntityMapsCacheModule, - PermissionsModule, - WorkspaceMigrationModule, ], controllers: [RouteTriggerController], - providers: [ - RouteTriggerService, - RouteTriggerV2Service, - WorkspaceFlatRouteTriggerMapCacheService, - RouteTriggerResolver, - ], - exports: [RouteTriggerV2Service, WorkspaceFlatRouteTriggerMapCacheService], + providers: [RouteTriggerService], + exports: [], }) export class RouteTriggerModule {} diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts index 426a491baf..a0d9287cf7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/route-trigger/route-trigger.service.ts @@ -4,7 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Request } from 'express'; import { match } from 'path-to-regexp'; import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils'; -import { Repository } from 'typeorm'; +import { IsNull, Not, Repository } from 'typeorm'; import { HTTPMethod } from 'twenty-shared/types'; import { AccessTokenService } from 'src/engine/core-modules/auth/token/services/access-token.service'; @@ -13,8 +13,8 @@ import { RouteTriggerException, RouteTriggerExceptionCode, } from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception'; -import { RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { buildServerlessFunctionEvent } from 'src/engine/metadata-modules/route-trigger/utils/build-serverless-function-event.util'; +import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service'; @Injectable() @@ -23,18 +23,18 @@ export class RouteTriggerService { private readonly accessTokenService: AccessTokenService, private readonly serverlessFunctionService: ServerlessFunctionService, private readonly workspaceDomainsService: WorkspaceDomainsService, - @InjectRepository(RouteTriggerEntity) - private readonly routeTriggerRepository: Repository, + @InjectRepository(ServerlessFunctionEntity) + private readonly serverlessFunctionRepository: Repository, ) {} - private async getOneRouteTriggerWithPathParamsOrFail({ + private async getServerlessFunctionWithPathParamsOrFail({ request, httpMethod, }: { request: Request; httpMethod: HTTPMethod; }): Promise<{ - routeTrigger: RouteTriggerEntity; + serverlessFunction: ServerlessFunctionEntity; pathParams: Partial>; }> { const host = `${request.protocol}://${request.get('host')}`; @@ -52,26 +52,35 @@ export class RouteTriggerService { ), ); - const routeTriggers = await this.routeTriggerRepository.find({ - where: { - httpMethod, - workspaceId: workspace.id, - }, - relations: ['serverlessFunction'], - }); + const serverlessFunctionsWithHttpRouteTrigger = + await this.serverlessFunctionRepository.find({ + where: { + workspaceId: workspace.id, + httpRouteTriggerSettings: Not(IsNull()), + }, + }); const requestPath = request.path.replace(/^\/s\//, '/'); - for (const routeTrigger of routeTriggers) { - const routeTriggerMatcher = match(routeTrigger.path, { + for (const serverlessFunction of serverlessFunctionsWithHttpRouteTrigger) { + const httpRouteSettings = serverlessFunction.httpRouteTriggerSettings; + + if ( + !isDefined(httpRouteSettings) || + httpRouteSettings.httpMethod !== httpMethod + ) { + continue; + } + + const routeMatcher = match(httpRouteSettings.path, { decode: decodeURIComponent, }); - const routeTriggerMatched = routeTriggerMatcher(requestPath); + const routeMatched = routeMatcher(requestPath); - if (routeTriggerMatched) { + if (routeMatched) { return { - routeTrigger, - pathParams: routeTriggerMatched.params, + serverlessFunction, + pathParams: routeMatched.params, }; } } @@ -116,30 +125,31 @@ export class RouteTriggerService { request: Request; httpMethod: HTTPMethod; }) { - const routeTriggerWithPathParams = - await this.getOneRouteTriggerWithPathParamsOrFail({ + const { serverlessFunction, pathParams } = + await this.getServerlessFunctionWithPathParamsOrFail({ request, httpMethod, }); - if (routeTriggerWithPathParams.routeTrigger.isAuthRequired) { + const httpRouteSettings = serverlessFunction.httpRouteTriggerSettings; + + if (httpRouteSettings?.isAuthRequired) { await this.validateWorkspaceFromRequest({ request, - workspaceId: routeTriggerWithPathParams.routeTrigger.workspaceId, + workspaceId: serverlessFunction.workspaceId, }); } const event = buildServerlessFunctionEvent({ request, - pathParameters: routeTriggerWithPathParams.pathParams, - forwardedRequestHeaders: - routeTriggerWithPathParams.routeTrigger.forwardedRequestHeaders ?? [], + pathParameters: pathParams, + forwardedRequestHeaders: httpRouteSettings?.forwardedRequestHeaders ?? [], }); const result = await this.serverlessFunctionService.executeOneServerlessFunction({ - id: routeTriggerWithPathParams.routeTrigger.serverlessFunction.id, - workspaceId: routeTriggerWithPathParams.routeTrigger.workspaceId, + id: serverlessFunction.id, + workspaceId: serverlessFunction.workspaceId, payload: event, version: '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 deleted file mode 100644 index 17a75c2b6f..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/route-trigger-v2.service.ts +++ /dev/null @@ -1,192 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { isDefined } from 'twenty-shared/utils'; - -import { ApplicationService } from 'src/engine/core-modules/application/application.service'; -import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-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 { type 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 { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception'; -import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service'; - -@Injectable() -export class RouteTriggerV2Service { - constructor( - private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService, - private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService, - private readonly applicationService: ApplicationService, - ) {} - - async createOne( - routeTriggerInput: CreateRouteTriggerInput, - workspaceId: string, - /** - * @deprecated do not use call validateBuildAndRunWorkspaceMigration contextually - * when interacting with another application than workspace custom one - * */ - applicationId?: string, - ): Promise { - const { workspaceCustomFlatApplication } = - await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow( - { - workspaceId, - }, - ); - - const flatRouteTriggerToCreate = - fromCreateRouteTriggerInputToFlatRouteTrigger({ - createRouteTriggerInput: routeTriggerInput, - workspaceId, - workspaceCustomApplicationId: - applicationId ?? workspaceCustomFlatApplication.id, - }); - - const validateAndBuildResult = - await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( - { - allFlatEntityOperationByMetadataName: { - routeTrigger: { - flatEntityToCreate: [flatRouteTriggerToCreate], - flatEntityToDelete: [], - flatEntityToUpdate: [], - }, - }, - workspaceId, - isSystemBuild: false, - }, - ); - - if (isDefined(validateAndBuildResult)) { - throw new WorkspaceMigrationBuilderException( - validateAndBuildResult, - 'Multiple validation errors occurred while creating route', - ); - } - - const { flatRouteTriggerMaps: recomputedExistingFlatRouteMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatRouteTriggerMaps'], - }, - ); - - return findFlatEntityByIdInFlatEntityMapsOrThrow({ - flatEntityId: flatRouteTriggerToCreate.id, - flatEntityMaps: recomputedExistingFlatRouteMaps, - }); - } - - async updateOne( - routeTriggerInput: UpdateRouteTriggerInput, - workspaceId: string, - ): Promise { - const { flatRouteTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatRouteTriggerMaps'], - }, - ); - - const optimisticallyUpdatedFlatRouteTrigger = - fromUpdateRouteTriggerInputToFlatRouteTriggerToUpdateOrThrow({ - flatRouteTriggerMaps, - updateRouteTriggerInput: routeTriggerInput, - }); - - const validateAndBuildResult = - await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( - { - allFlatEntityOperationByMetadataName: { - routeTrigger: { - flatEntityToCreate: [], - flatEntityToDelete: [], - flatEntityToUpdate: [optimisticallyUpdatedFlatRouteTrigger], - }, - }, - workspaceId, - isSystemBuild: false, - }, - ); - - if (isDefined(validateAndBuildResult)) { - throw new WorkspaceMigrationBuilderException( - validateAndBuildResult, - 'Multiple validation errors occurred while updating route', - ); - } - - const { flatRouteTriggerMaps: recomputedExistingFlatRouteMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatRouteTriggerMaps'], - }, - ); - - return findFlatEntityByIdInFlatEntityMapsOrThrow({ - flatEntityId: optimisticallyUpdatedFlatRouteTrigger.id, - flatEntityMaps: recomputedExistingFlatRouteMaps, - }); - } - - async destroyOne({ - destroyRouteTriggerInput, - workspaceId, - }: { - destroyRouteTriggerInput: RouteTriggerIdInput; - workspaceId: string; - }): Promise { - const { flatRouteTriggerMaps } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: ['flatRouteTriggerMaps'], - }, - ); - - const existingFlatRoute = - flatRouteTriggerMaps.byId[destroyRouteTriggerInput.id]; - - if (!isDefined(existingFlatRoute)) { - throw new RouteTriggerException( - 'Route to destroy not found', - RouteTriggerExceptionCode.ROUTE_NOT_FOUND, - ); - } - - const validateAndBuildResult = - await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration( - { - allFlatEntityOperationByMetadataName: { - routeTrigger: { - flatEntityToCreate: [], - flatEntityToDelete: [existingFlatRoute], - flatEntityToUpdate: [], - }, - }, - workspaceId, - isSystemBuild: false, - }, - ); - - if (isDefined(validateAndBuildResult)) { - throw new WorkspaceMigrationBuilderException( - 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 deleted file mode 100644 index a75476669d..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/services/workspace-flat-route-trigger-map-cache.service.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; - -import { removePropertiesFromRecord } from 'twenty-shared/utils'; -import { Repository } from 'typeorm'; - -import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service'; - -import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant'; -import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { getMetadataEntityRelationProperties } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-entity-relation-properties.util'; -import { RouteTriggerEntity } 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 { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator'; -import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util'; - -@Injectable() -@WorkspaceCache('flatRouteTriggerMaps') -export class WorkspaceFlatRouteTriggerMapCacheService extends WorkspaceCacheProvider< - FlatEntityMaps -> { - constructor( - @InjectRepository(RouteTriggerEntity) - private readonly routeTriggerRepository: Repository, - ) { - super(); - } - - async computeForCache( - workspaceId: string, - ): Promise> { - const routeTriggers = await this.routeTriggerRepository.find({ - where: { - workspaceId, - }, - }); - - const flatRouteTriggerMaps = createEmptyFlatEntityMaps(); - - for (const routeTriggerEntity of routeTriggers) { - const routeTriggerEntityWithoutRelations = removePropertiesFromRecord( - routeTriggerEntity, - getMetadataEntityRelationProperties('routeTrigger'), - ); - const flatRouteTrigger = { - ...routeTriggerEntityWithoutRelations, - createdAt: routeTriggerEntity.createdAt.toISOString(), - updatedAt: routeTriggerEntity.updatedAt.toISOString(), - universalIdentifier: routeTriggerEntity.universalIdentifier, - } satisfies FlatRouteTrigger; - - addFlatEntityToFlatEntityMapsThroughMutationOrThrow({ - flatEntity: flatRouteTrigger, - flatEntityMapsToMutate: flatRouteTriggerMaps, - }); - } - - return flatRouteTriggerMaps; - } -} 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 deleted file mode 100644 index d88b18b210..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type'; -import { type RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; - -export type FlatRouteTrigger = FlatEntityFrom; 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 deleted file mode 100644 index c33b4305d5..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-create-route-trigger-input-to-flat-route-trigger.util.ts +++ /dev/null @@ -1,33 +0,0 @@ -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, - workspaceCustomApplicationId, -}: { - createRouteTriggerInput: CreateRouteTriggerInput; - workspaceId: string; - workspaceCustomApplicationId: string; -}): FlatRouteTrigger => { - const now = new Date(); - const id = uuidV4(); - - return { - id, - universalIdentifier: - createRouteTriggerInput.universalIdentifier ?? uuidV4(), - path: createRouteTriggerInput.path, - isAuthRequired: createRouteTriggerInput.isAuthRequired, - httpMethod: createRouteTriggerInput.httpMethod, - forwardedRequestHeaders: - createRouteTriggerInput.forwardedRequestHeaders ?? [], - serverlessFunctionId: createRouteTriggerInput.serverlessFunctionId, - workspaceId, - createdAt: now.toISOString(), - updatedAt: now.toISOString(), - applicationId: workspaceCustomApplicationId, - }; -}; diff --git a/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-flat-route-trigger-to-route-trigger-dto.util.ts b/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-flat-route-trigger-to-route-trigger-dto.util.ts deleted file mode 100644 index f925a3d146..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/from-flat-route-trigger-to-route-trigger-dto.util.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { type RouteTriggerDTO } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto'; -import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; - -export const fromFlatRouteTriggerToRouteTriggerDto = ( - flatRouteTrigger: FlatRouteTrigger, -): RouteTriggerDTO => ({ - id: flatRouteTrigger.id, - path: flatRouteTrigger.path, - isAuthRequired: flatRouteTrigger.isAuthRequired, - httpMethod: flatRouteTrigger.httpMethod, - forwardedRequestHeaders: flatRouteTrigger.forwardedRequestHeaders, - createdAt: new Date(flatRouteTrigger.createdAt), - updatedAt: new Date(flatRouteTrigger.updatedAt), -}); 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 deleted file mode 100644 index 5364de7457..0000000000 --- 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 +++ /dev/null @@ -1,36 +0,0 @@ -import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/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, - updatedAt: new Date().toISOString(), - path: updateRouteTriggerInput.update.path, - isAuthRequired: updateRouteTriggerInput.update.isAuthRequired, - httpMethod: updateRouteTriggerInput.update.httpMethod, - forwardedRequestHeaders: - updateRouteTriggerInput.update.forwardedRequestHeaders ?? - existingFlatRouteTrigger.forwardedRequestHeaders, - }; -}; 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 deleted file mode 100644 index fd82c2e35b..0000000000 --- a/packages/twenty-server/src/engine/metadata-modules/route-trigger/utils/route-trigger-graphql-api-exception-handler.utils.ts +++ /dev/null @@ -1,23 +0,0 @@ -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): never => { - 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/serverless-function/dtos/serverless-function.dto.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/serverless-function.dto.ts index 831ace2ea6..91f26298a7 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/serverless-function.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/serverless-function.dto.ts @@ -19,9 +19,11 @@ import { import graphqlTypeJson from 'graphql-type-json'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; -import { CronTriggerDTO } from 'src/engine/metadata-modules/cron-trigger/dtos/cron-trigger.dto'; -import { DatabaseEventTriggerDTO } from 'src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger.dto'; -import { RouteTriggerDTO } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto'; +import { + CronTriggerSettings, + DatabaseEventTriggerSettings, + HttpRouteTriggerSettings, +} from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; @ObjectType('ServerlessFunction') @Authorize({ @@ -86,14 +88,20 @@ export class ServerlessFunctionDTO { @Field() isTool: boolean; - @Field(() => [CronTriggerDTO], { nullable: true }) - cronTriggers?: CronTriggerDTO[]; + @IsObject() + @IsOptional() + @Field(() => graphqlTypeJson, { nullable: true }) + cronTriggerSettings?: CronTriggerSettings; - @Field(() => [DatabaseEventTriggerDTO], { nullable: true }) - databaseEventTriggers?: DatabaseEventTriggerDTO[]; + @IsObject() + @IsOptional() + @Field(() => graphqlTypeJson, { nullable: true }) + databaseEventTriggerSettings?: DatabaseEventTriggerSettings; - @Field(() => [RouteTriggerDTO], { nullable: true }) - routeTriggers?: RouteTriggerDTO[]; + @IsObject() + @IsOptional() + @Field(() => graphqlTypeJson, { nullable: true }) + httpRouteTriggerSettings?: HttpRouteTriggerSettings; @IsUUID() @IsOptional() 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 0836ee9af7..20d39957f6 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 @@ -1,3 +1,4 @@ +import { HTTPMethod } from 'twenty-shared/types'; import { Check, Column, @@ -7,19 +8,31 @@ import { Index, JoinColumn, ManyToOne, - OneToMany, PrimaryGeneratedColumn, Relation, UpdateDateColumn, } from 'typeorm'; import { type JsonbProperty } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/types/jsonb-property.type'; -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; -import { RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { ServerlessFunctionLayerEntity } from 'src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.entity'; import { SyncableEntity } from 'src/engine/workspace-manager/types/syncable-entity.interface'; +export type CronTriggerSettings = { + pattern: string; +}; + +export type DatabaseEventTriggerSettings = { + eventName: string; + updatedFields?: string[]; +}; + +export type HttpRouteTriggerSettings = { + path: string; + httpMethod: HTTPMethod; + isAuthRequired: boolean; + forwardedRequestHeaders?: string[]; +}; + const DEFAULT_SERVERLESS_TIMEOUT_SECONDS = 300; // 5 minutes export enum ServerlessFunctionRuntime { @@ -89,32 +102,14 @@ export class ServerlessFunctionEntity @JoinColumn({ name: 'serverlessFunctionLayerId' }) serverlessFunctionLayer: Relation; - @OneToMany( - () => CronTriggerEntity, - (cronTrigger) => cronTrigger.serverlessFunction, - { - cascade: true, - }, - ) - cronTriggers: CronTriggerEntity[]; + @Column({ nullable: true, type: 'jsonb' }) + cronTriggerSettings: JsonbProperty | null; - @OneToMany( - () => DatabaseEventTriggerEntity, - (databaseEventTrigger) => databaseEventTrigger.serverlessFunction, - { - cascade: true, - }, - ) - databaseEventTriggers: DatabaseEventTriggerEntity[]; + @Column({ nullable: true, type: 'jsonb' }) + databaseEventTriggerSettings: JsonbProperty | null; - @OneToMany( - () => RouteTriggerEntity, - (routeTrigger) => routeTrigger.serverlessFunction, - { - cascade: true, - }, - ) - routeTriggers: RouteTriggerEntity[]; + @Column({ nullable: true, type: 'jsonb' }) + httpRouteTriggerSettings: JsonbProperty | null; @CreateDateColumn({ type: 'timestamptz' }) createdAt: Date; diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.module.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.module.ts index 63a95e1cc8..3371757e56 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.module.ts @@ -12,11 +12,8 @@ import { FileUploadModule } from 'src/engine/core-modules/file/file-upload/file- import { FileModule } from 'src/engine/core-modules/file/file.module'; import { SecretEncryptionModule } from 'src/engine/core-modules/secret-encryption/secret-encryption.module'; import { ThrottlerModule } from 'src/engine/core-modules/throttler/throttler.module'; -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; -import { RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { ServerlessFunctionLayerModule } from 'src/engine/metadata-modules/serverless-function-layer/serverless-function-layer.module'; import { ServerlessFunctionTriggerJob } from 'src/engine/metadata-modules/serverless-function/jobs/serverless-function-trigger.job'; import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; @@ -33,12 +30,7 @@ import { FunctionBuildModule } from 'src/engine/metadata-modules/function-build/ imports: [ FileUploadModule, NestjsQueryTypeOrmModule.forFeature([ServerlessFunctionEntity]), - TypeOrmModule.forFeature([ - FeatureFlagEntity, - DatabaseEventTriggerEntity, - CronTriggerEntity, - RouteTriggerEntity, - ]), + TypeOrmModule.forFeature([FeatureFlagEntity]), FileModule, ThrottlerModule, ApplicationModule, diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.resolver.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.resolver.ts index 092b7fbe85..3f31e80598 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.resolver.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/serverless-function.resolver.ts @@ -52,21 +52,11 @@ export class ServerlessFunctionResolver { @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, ): Promise { try { - const { - flatServerlessFunctionMaps, - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, - } = + const { flatServerlessFunctionMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatMapsKeys: [ - 'flatServerlessFunctionMaps', - 'flatCronTriggerMaps', - 'flatDatabaseEventTriggerMaps', - 'flatRouteTriggerMaps', - ], + flatMapsKeys: ['flatServerlessFunctionMaps'], }, ); @@ -77,9 +67,6 @@ export class ServerlessFunctionResolver { return fromFlatServerlessFunctionToServerlessFunctionDto({ flatServerlessFunction, - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, }); } catch (error) { return serverlessFunctionGraphQLApiExceptionHandler(error); @@ -91,21 +78,11 @@ export class ServerlessFunctionResolver { @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, ): Promise { try { - const { - flatServerlessFunctionMaps, - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, - } = + const { flatServerlessFunctionMaps } = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( { workspaceId, - flatMapsKeys: [ - 'flatServerlessFunctionMaps', - 'flatCronTriggerMaps', - 'flatDatabaseEventTriggerMaps', - 'flatRouteTriggerMaps', - ], + flatMapsKeys: ['flatServerlessFunctionMaps'], }, ); @@ -120,9 +97,6 @@ export class ServerlessFunctionResolver { .map((flatServerlessFunction) => fromFlatServerlessFunctionToServerlessFunctionDto({ flatServerlessFunction, - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, }), ); } catch (error) { @@ -168,27 +142,8 @@ export class ServerlessFunctionResolver { workspaceId, }); - const { - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, - } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatCronTriggerMaps', - 'flatDatabaseEventTriggerMaps', - 'flatRouteTriggerMaps', - ], - }, - ); - return fromFlatServerlessFunctionToServerlessFunctionDto({ flatServerlessFunction, - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, }); } catch (error) { return serverlessFunctionGraphQLApiExceptionHandler(error); @@ -209,27 +164,8 @@ export class ServerlessFunctionResolver { workspaceId, ); - const { - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, - } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatCronTriggerMaps', - 'flatDatabaseEventTriggerMaps', - 'flatRouteTriggerMaps', - ], - }, - ); - return fromFlatServerlessFunctionToServerlessFunctionDto({ flatServerlessFunction, - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, }); } catch (error) { return serverlessFunctionGraphQLApiExceptionHandler(error); @@ -250,27 +186,8 @@ export class ServerlessFunctionResolver { workspaceId, ); - const { - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, - } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatCronTriggerMaps', - 'flatDatabaseEventTriggerMaps', - 'flatRouteTriggerMaps', - ], - }, - ); - return fromFlatServerlessFunctionToServerlessFunctionDto({ flatServerlessFunction, - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, }); } catch (error) { return serverlessFunctionGraphQLApiExceptionHandler(error); @@ -312,27 +229,8 @@ export class ServerlessFunctionResolver { workspaceId, ); - const { - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, - } = - await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( - { - workspaceId, - flatMapsKeys: [ - 'flatCronTriggerMaps', - 'flatDatabaseEventTriggerMaps', - 'flatRouteTriggerMaps', - ], - }, - ); - return fromFlatServerlessFunctionToServerlessFunctionDto({ flatServerlessFunction, - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, }); } catch (error) { return serverlessFunctionGraphQLApiExceptionHandler(error); diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/workspace-flat-serverless-function-map-cache.service.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/workspace-flat-serverless-function-map-cache.service.ts index e1eb992f26..f1eaeb3c43 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/workspace-flat-serverless-function-map-cache.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/services/workspace-flat-serverless-function-map-cache.service.ts @@ -5,16 +5,12 @@ import { Repository } from 'typeorm'; import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service'; -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant'; import { FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; import { FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type'; import { fromServerlessFunctionEntityToFlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/utils/from-serverless-function-entity-to-flat-serverless-function.util'; import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator'; -import { regroupEntitiesByRelatedEntityId } from 'src/engine/workspace-cache/utils/regroup-entities-by-related-entity-id'; import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util'; @Injectable() @@ -25,12 +21,6 @@ export class WorkspaceFlatServerlessFunctionMapCacheService extends WorkspaceCac constructor( @InjectRepository(ServerlessFunctionEntity) private readonly serverlessFunctionRepository: Repository, - @InjectRepository(DatabaseEventTriggerEntity) - private readonly databaseEventTriggerRepository: Repository, - @InjectRepository(CronTriggerEntity) - private readonly cronTriggerRepository: Repository, - @InjectRepository(RouteTriggerEntity) - private readonly routeTriggerRepository: Repository, ) { super(); } @@ -38,73 +28,18 @@ export class WorkspaceFlatServerlessFunctionMapCacheService extends WorkspaceCac async computeForCache( workspaceId: string, ): Promise> { - const [ - serverlessFunctions, - routeTriggers, - cronTriggers, - databaseEventTriggers, - ] = await Promise.all([ - this.serverlessFunctionRepository.find({ - where: { workspaceId }, - withDeleted: true, - }), - this.cronTriggerRepository.find({ - where: { workspaceId }, - select: ['id', 'serverlessFunctionId'], - withDeleted: true, - }), - this.routeTriggerRepository.find({ - where: { workspaceId }, - select: ['id', 'serverlessFunctionId'], - withDeleted: true, - }), - this.databaseEventTriggerRepository.find({ - where: { workspaceId }, - select: ['id', 'serverlessFunctionId'], - withDeleted: true, - }), - ]); - - const [ - routeTriggersByServerlessFunctionId, - cronTriggersByServerlessFunctionId, - databaseEventTriggersByServerlessFunctionId, - ] = ( - [ - { - entities: routeTriggers, - foreignKey: 'serverlessFunctionId', - }, - { - entities: cronTriggers, - foreignKey: 'serverlessFunctionId', - }, - { - entities: databaseEventTriggers, - foreignKey: 'serverlessFunctionId', - }, - ] as const - ).map(regroupEntitiesByRelatedEntityId); + const serverlessFunctions = await this.serverlessFunctionRepository.find({ + where: { workspaceId }, + withDeleted: true, + }); const flatServerlessFunctionMaps = createEmptyFlatEntityMaps(); for (const serverlessFunctionEntity of serverlessFunctions) { const flatServerlessFunction = - fromServerlessFunctionEntityToFlatServerlessFunction({ - ...serverlessFunctionEntity, - routeTriggers: - routeTriggersByServerlessFunctionId.get( - serverlessFunctionEntity.id, - ) || [], - cronTriggers: - cronTriggersByServerlessFunctionId.get( - serverlessFunctionEntity.id, - ) || [], - databaseEventTriggers: - databaseEventTriggersByServerlessFunctionId.get( - serverlessFunctionEntity.id, - ) || [], - } as ServerlessFunctionEntity); + fromServerlessFunctionEntityToFlatServerlessFunction( + serverlessFunctionEntity, + ); addFlatEntityToFlatEntityMapsThroughMutationOrThrow({ flatEntity: flatServerlessFunction, diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-create-serverless-function-input-to-flat-serverless-function.util.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-create-serverless-function-input-to-flat-serverless-function.util.ts index 162cba6c1c..d945a3373b 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-create-serverless-function-input-to-flat-serverless-function.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-create-serverless-function-input-to-flat-serverless-function.util.ts @@ -29,10 +29,10 @@ export const fromCreateServerlessFunctionInputToFlatServerlessFunction = ({ const currentDate = new Date(); return { - cronTriggerIds: [], - databaseEventTriggerIds: [], - routeTriggerIds: [], id, + cronTriggerSettings: null, + databaseEventTriggerSettings: null, + httpRouteTriggerSettings: null, name: rawCreateServerlessFunctionInput.name, description: rawCreateServerlessFunctionInput.description ?? null, sourceHandlerPath: diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-flat-serverless-function-to-serverless-function-dto.util.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-flat-serverless-function-to-serverless-function-dto.util.ts index 30f358b546..05751b9442 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-flat-serverless-function-to-serverless-function-dto.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-flat-serverless-function-to-serverless-function-dto.util.ts @@ -1,41 +1,11 @@ -import { isDefined } from 'twenty-shared/utils'; - -import { type FlatCronTrigger } from 'src/engine/metadata-modules/cron-trigger/types/flat-cron-trigger.type'; -import { fromFlatCronTriggerToCronTriggerDto } from 'src/engine/metadata-modules/cron-trigger/utils/from-flat-cron-trigger-to-cron-trigger-dto.util'; -import { type FlatDatabaseEventTrigger } from 'src/engine/metadata-modules/database-event-trigger/types/flat-database-event-trigger.type'; -import { fromFlatDatabaseEventTriggerToDatabaseEventTriggerDto } from 'src/engine/metadata-modules/database-event-trigger/utils/from-flat-database-event-trigger-to-database-event-trigger-dto.util'; -import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type'; -import { type FlatRouteTrigger } from 'src/engine/metadata-modules/route-trigger/types/flat-route-trigger.type'; -import { fromFlatRouteTriggerToRouteTriggerDto } from 'src/engine/metadata-modules/route-trigger/utils/from-flat-route-trigger-to-route-trigger-dto.util'; import { type ServerlessFunctionDTO } from 'src/engine/metadata-modules/serverless-function/dtos/serverless-function.dto'; import { type FlatServerlessFunction } from 'src/engine/metadata-modules/serverless-function/types/flat-serverless-function.type'; export const fromFlatServerlessFunctionToServerlessFunctionDto = ({ flatServerlessFunction, - flatCronTriggerMaps, - flatDatabaseEventTriggerMaps, - flatRouteTriggerMaps, }: { flatServerlessFunction: FlatServerlessFunction; - flatCronTriggerMaps: FlatEntityMaps; - flatDatabaseEventTriggerMaps: FlatEntityMaps; - flatRouteTriggerMaps: FlatEntityMaps; }): ServerlessFunctionDTO => { - const cronTriggers = flatServerlessFunction.cronTriggerIds - .map((id) => flatCronTriggerMaps.byId[id]) - .filter(isDefined) - .map(fromFlatCronTriggerToCronTriggerDto); - - const databaseEventTriggers = flatServerlessFunction.databaseEventTriggerIds - .map((id) => flatDatabaseEventTriggerMaps.byId[id]) - .filter(isDefined) - .map(fromFlatDatabaseEventTriggerToDatabaseEventTriggerDto); - - const routeTriggers = flatServerlessFunction.routeTriggerIds - .map((id) => flatRouteTriggerMaps.byId[id]) - .filter(isDefined) - .map(fromFlatRouteTriggerToRouteTriggerDto); - return { id: flatServerlessFunction.id, name: flatServerlessFunction.name, @@ -53,8 +23,11 @@ export const fromFlatServerlessFunctionToServerlessFunctionDto = ({ workspaceId: flatServerlessFunction.workspaceId, createdAt: new Date(flatServerlessFunction.createdAt), updatedAt: new Date(flatServerlessFunction.updatedAt), - cronTriggers, - databaseEventTriggers, - routeTriggers, + cronTriggerSettings: + flatServerlessFunction.cronTriggerSettings ?? undefined, + databaseEventTriggerSettings: + flatServerlessFunction.databaseEventTriggerSettings ?? undefined, + httpRouteTriggerSettings: + flatServerlessFunction.httpRouteTriggerSettings ?? undefined, }; }; diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-serverless-function-entity-to-flat-serverless-function.util.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-serverless-function-entity-to-flat-serverless-function.util.ts index 35a90054eb..845be3091e 100644 --- a/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-serverless-function-entity-to-flat-serverless-function.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/utils/from-serverless-function-entity-to-flat-serverless-function.util.ts @@ -8,13 +8,7 @@ export const fromServerlessFunctionEntityToFlatServerlessFunction = ( ): FlatServerlessFunction => { const serverlessFunctionWithoutRelations = removePropertiesFromRecord( serverlessFunctionEntity, - [ - 'databaseEventTriggers', - 'routeTriggers', - 'cronTriggers', - 'serverlessFunctionLayer', - 'application', - ], + ['serverlessFunctionLayer', 'application'], ); return { @@ -22,12 +16,6 @@ export const fromServerlessFunctionEntityToFlatServerlessFunction = ( createdAt: serverlessFunctionEntity.createdAt.toISOString(), updatedAt: serverlessFunctionEntity.updatedAt.toISOString(), deletedAt: serverlessFunctionEntity.deletedAt?.toISOString() ?? null, - cronTriggerIds: - serverlessFunctionEntity.cronTriggers.map((el) => el.id) ?? [], - routeTriggerIds: - serverlessFunctionEntity.routeTriggers.map((el) => el.id) ?? [], - databaseEventTriggerIds: - serverlessFunctionEntity.databaseEventTriggers.map((el) => el.id) ?? [], universalIdentifier: serverlessFunctionEntity.universalIdentifier, }; }; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-build-orchestrator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-build-orchestrator.service.ts index 91fa31ea77..e730e41183 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-build-orchestrator.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-build-orchestrator.service.ts @@ -16,8 +16,6 @@ import { import { aggregateOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-orchestrator-actions-report.util'; import { WorkspaceMigrationAgentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/workspace-migration-agent-actions-builder.service'; import { WorkspaceMigrationCommandMenuItemActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/workspace-migration-command-menu-item-actions-builder.service'; -import { WorkspaceMigrationCronTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/workspace-migration-cron-trigger-action-builder.service'; -import { WorkspaceMigrationDatabaseEventTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/workspace-migration-database-event-trigger-actions-builder.service'; import { WorkspaceMigrationFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/workspace-migration-field-actions-builder.service'; import { WorkspaceMigrationFrontComponentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/front-component/workspace-migration-front-component-actions-builder.service'; import { WorkspaceMigrationIndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/index/workspace-migration-index-actions-builder.service'; @@ -28,7 +26,6 @@ import { WorkspaceMigrationPageLayoutWidgetActionsBuilderService } from 'src/eng import { WorkspaceMigrationPageLayoutActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/workspace-migration-page-layout-actions-builder.service'; import { WorkspaceMigrationRoleTargetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role-target/workspace-migration-role-target-actions-builder.service'; import { WorkspaceMigrationRoleActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role/workspace-migration-role-actions-builder.service'; -import { WorkspaceMigrationRouteTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/workspace-migration-route-trigger-actions-builder.service'; import { WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate-group/workspace-migration-row-level-permission-predicate-group-actions-builder.service'; import { WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate/workspace-migration-row-level-permission-predicate-actions-builder.service'; import { WorkspaceMigrationServerlessFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/serverless-function/workspace-migration-serverless-function-actions-builder.service'; @@ -51,9 +48,6 @@ export class WorkspaceMigrationBuildOrchestratorService { private readonly workspaceMigrationViewFilterGroupActionsBuilderService: WorkspaceMigrationViewFilterGroupActionsBuilderService, private readonly workspaceMigrationViewGroupActionsBuilderService: WorkspaceMigrationViewGroupActionsBuilderService, private readonly workspaceMigrationServerlessFunctionActionsBuilderService: WorkspaceMigrationServerlessFunctionActionsBuilderService, - private readonly workspaceMigrationDatabaseEventTriggerActionsBuilderService: WorkspaceMigrationDatabaseEventTriggerActionsBuilderService, - private readonly workspaceMigrationCronTriggerActionsBuilderService: WorkspaceMigrationCronTriggerActionsBuilderService, - private readonly workspaceMigrationRouteTriggerActionsBuilderService: WorkspaceMigrationRouteTriggerActionsBuilderService, private readonly workspaceMigrationRoleTargetActionsBuilderService: WorkspaceMigrationRoleTargetActionsBuilderService, private readonly workspaceMigrationFieldActionsBuilderService: WorkspaceMigrationFieldActionsBuilderService, private readonly workspaceMigrationRoleActionsBuilderService: WorkspaceMigrationRoleActionsBuilderService, @@ -151,9 +145,6 @@ export class WorkspaceMigrationBuildOrchestratorService { flatViewMaps, flatIndexMaps, flatServerlessFunctionMaps, - flatDatabaseEventTriggerMaps, - flatCronTriggerMaps, - flatRouteTriggerMaps, flatFieldMetadataMaps, flatViewFilterMaps, flatViewFilterGroupMaps, @@ -591,115 +582,6 @@ export class WorkspaceMigrationBuildOrchestratorService { } } - if (isDefined(flatDatabaseEventTriggerMaps)) { - const { - from: fromFlatDatabaseEventTriggerMaps, - to: toFlatDatabaseEventTriggerMaps, - } = flatDatabaseEventTriggerMaps; - - const databaseEventTriggerResult = - await this.workspaceMigrationDatabaseEventTriggerActionsBuilderService.validateAndBuild( - { - additionalCacheDataMaps, - from: fromFlatDatabaseEventTriggerMaps, - to: toFlatDatabaseEventTriggerMaps, - buildOptions, - dependencyOptimisticFlatEntityMaps: { - flatServerlessFunctionMaps: - optimisticAllFlatEntityMaps.flatServerlessFunctionMaps, - }, - workspaceId, - }, - ); - - this.mergeFlatEntityMapsAndRelatedFlatEntityMapsInAllFlatEntityMapsThroughMutation( - { - allFlatEntityMaps: optimisticAllFlatEntityMaps, - flatEntityMapsAndRelatedFlatEntityMaps: - databaseEventTriggerResult.optimisticFlatEntityMapsAndRelatedFlatEntityMaps, - }, - ); - - if (databaseEventTriggerResult.status === 'fail') { - orchestratorFailureReport.databaseEventTrigger.push( - ...databaseEventTriggerResult.errors, - ); - } else { - orchestratorActionsReport.databaseEventTrigger = - databaseEventTriggerResult.actions; - } - } - - if (isDefined(flatCronTriggerMaps)) { - const { from: fromFlatCronTriggerMaps, to: toFlatCronTriggerMaps } = - flatCronTriggerMaps; - - const cronTriggerResult = - await this.workspaceMigrationCronTriggerActionsBuilderService.validateAndBuild( - { - additionalCacheDataMaps, - from: fromFlatCronTriggerMaps, - to: toFlatCronTriggerMaps, - buildOptions, - dependencyOptimisticFlatEntityMaps: { - flatServerlessFunctionMaps: - optimisticAllFlatEntityMaps.flatServerlessFunctionMaps, - }, - workspaceId, - }, - ); - - this.mergeFlatEntityMapsAndRelatedFlatEntityMapsInAllFlatEntityMapsThroughMutation( - { - allFlatEntityMaps: optimisticAllFlatEntityMaps, - flatEntityMapsAndRelatedFlatEntityMaps: - cronTriggerResult.optimisticFlatEntityMapsAndRelatedFlatEntityMaps, - }, - ); - - if (cronTriggerResult.status === 'fail') { - orchestratorFailureReport.cronTrigger.push(...cronTriggerResult.errors); - } else { - orchestratorActionsReport.cronTrigger = cronTriggerResult.actions; - } - } - - if (isDefined(flatRouteTriggerMaps)) { - const { from: fromFlatRouteTriggerMaps, to: toFlatRouteTriggerMaps } = - flatRouteTriggerMaps; - - const routeTriggerResult = - await this.workspaceMigrationRouteTriggerActionsBuilderService.validateAndBuild( - { - additionalCacheDataMaps, - from: fromFlatRouteTriggerMaps, - to: toFlatRouteTriggerMaps, - buildOptions, - dependencyOptimisticFlatEntityMaps: { - flatServerlessFunctionMaps: - optimisticAllFlatEntityMaps.flatServerlessFunctionMaps, - }, - workspaceId, - }, - ); - - this.mergeFlatEntityMapsAndRelatedFlatEntityMapsInAllFlatEntityMapsThroughMutation( - { - allFlatEntityMaps: optimisticAllFlatEntityMaps, - flatEntityMapsAndRelatedFlatEntityMaps: - routeTriggerResult.optimisticFlatEntityMapsAndRelatedFlatEntityMaps, - }, - ); - - if (routeTriggerResult.status === 'fail') { - orchestratorFailureReport.routeTrigger.push( - ...routeTriggerResult.errors, - ); - } else { - orchestratorActionsReport.routeTrigger = routeTriggerResult.actions; - } - } - if (isDefined(flatRoleMaps)) { const { from: fromFlatRoleMaps, to: toFlatRoleMaps } = flatRoleMaps; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/types/workspace-migration-cron-trigger-action.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/types/workspace-migration-cron-trigger-action.type.ts deleted file mode 100644 index 41946b8f59..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/types/workspace-migration-cron-trigger-action.type.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type'; -import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type'; -import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type'; - -export type CreateCronTriggerAction = - BaseCreateWorkspaceMigrationAction<'cronTrigger'>; - -export type UpdateCronTriggerAction = - BaseUpdateWorkspaceMigrationAction<'cronTrigger'>; - -export type DeleteCronTriggerAction = - BaseDeleteWorkspaceMigrationAction<'cronTrigger'>; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/workspace-migration-cron-trigger-action-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/workspace-migration-cron-trigger-action-builder.service.ts deleted file mode 100644 index 2fb7a0e03d..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/workspace-migration-cron-trigger-action-builder.service.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { ALL_METADATA_NAME } from 'twenty-shared/metadata'; - -import { UpdateCronTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/types/workspace-migration-cron-trigger-action.type'; -import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service'; -import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type'; -import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type'; -import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type'; -import { FlatCronTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-cron-trigger-validator.service'; - -@Injectable() -export class WorkspaceMigrationCronTriggerActionsBuilderService extends WorkspaceEntityMigrationBuilderService< - typeof ALL_METADATA_NAME.cronTrigger -> { - constructor( - private readonly flatCronTriggerValidatorService: FlatCronTriggerValidatorService, - ) { - super(ALL_METADATA_NAME.cronTrigger); - } - - protected validateFlatEntityCreation( - args: FlatEntityValidationArgs, - ): FlatEntityValidationReturnType< - typeof ALL_METADATA_NAME.cronTrigger, - 'create' - > { - const validationResult = - this.flatCronTriggerValidatorService.validateFlatCronTriggerCreation( - args, - ); - - if (validationResult.errors.length > 0) { - return { - status: 'fail', - ...validationResult, - }; - } - - const { flatEntityToValidate: flatCronTriggerToValidate } = args; - - return { - status: 'success', - action: { - type: 'create', - metadataName: 'cronTrigger', - flatEntity: flatCronTriggerToValidate, - }, - }; - } - - protected validateFlatEntityDeletion( - args: FlatEntityValidationArgs, - ): FlatEntityValidationReturnType< - typeof ALL_METADATA_NAME.cronTrigger, - 'delete' - > { - const validationResult = - this.flatCronTriggerValidatorService.validateFlatCronTriggerDeletion( - args, - ); - - if (validationResult.errors.length > 0) { - return { - status: 'fail', - ...validationResult, - }; - } - - const { flatEntityToValidate: flatCronTriggerToValidate } = args; - - return { - status: 'success', - action: { - type: 'delete', - metadataName: 'cronTrigger', - universalIdentifier: flatCronTriggerToValidate.universalIdentifier, - }, - }; - } - - protected validateFlatEntityUpdate( - args: FlatEntityUpdateValidationArgs, - ): FlatEntityValidationReturnType< - typeof ALL_METADATA_NAME.cronTrigger, - 'update' - > { - const validationResult = - this.flatCronTriggerValidatorService.validateFlatCronTriggerUpdate(args); - - if (validationResult.errors.length > 0) { - return { - status: 'fail', - ...validationResult, - }; - } - const { flatEntityId, flatEntityUpdates } = args; - - const updateCronTriggerAction: UpdateCronTriggerAction = { - type: 'update', - metadataName: 'cronTrigger', - entityId: flatEntityId, - updates: flatEntityUpdates, - }; - - return { - status: 'success', - action: updateCronTriggerAction, - }; - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/types/workspace-migration-database-event-trigger-action.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/types/workspace-migration-database-event-trigger-action.type.ts deleted file mode 100644 index aa4ba4c032..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/types/workspace-migration-database-event-trigger-action.type.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type'; -import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type'; -import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type'; - -export type CreateDatabaseEventTriggerAction = - BaseCreateWorkspaceMigrationAction<'databaseEventTrigger'>; - -export type UpdateDatabaseEventTriggerAction = - BaseUpdateWorkspaceMigrationAction<'databaseEventTrigger'>; - -export type DeleteDatabaseEventTriggerAction = - BaseDeleteWorkspaceMigrationAction<'databaseEventTrigger'>; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/workspace-migration-database-event-trigger-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/workspace-migration-database-event-trigger-actions-builder.service.ts deleted file mode 100644 index 49ad12fb39..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/workspace-migration-database-event-trigger-actions-builder.service.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { ALL_METADATA_NAME } from 'twenty-shared/metadata'; - -import { UpdateDatabaseEventTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/types/workspace-migration-database-event-trigger-action.type'; -import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service'; -import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type'; -import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type'; -import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type'; -import { FlatDatabaseEventTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-database-event-trigger-validator.service'; - -@Injectable() -export class WorkspaceMigrationDatabaseEventTriggerActionsBuilderService extends WorkspaceEntityMigrationBuilderService< - typeof ALL_METADATA_NAME.databaseEventTrigger -> { - constructor( - private readonly flatDatabaseEventTriggerValidatorService: FlatDatabaseEventTriggerValidatorService, - ) { - super(ALL_METADATA_NAME.databaseEventTrigger); - } - - protected validateFlatEntityCreation( - args: FlatEntityValidationArgs< - typeof ALL_METADATA_NAME.databaseEventTrigger - >, - ): FlatEntityValidationReturnType< - typeof ALL_METADATA_NAME.databaseEventTrigger, - 'create' - > { - const validationResult = - this.flatDatabaseEventTriggerValidatorService.validateFlatDatabaseEventTriggerCreation( - args, - ); - - if (validationResult.errors.length > 0) { - return { - status: 'fail', - ...validationResult, - }; - } - - const { flatEntityToValidate: flatDatabaseEventTriggerToValidate } = args; - - return { - status: 'success', - action: { - type: 'create', - metadataName: 'databaseEventTrigger', - flatEntity: flatDatabaseEventTriggerToValidate, - }, - }; - } - - protected validateFlatEntityDeletion( - args: FlatEntityValidationArgs< - typeof ALL_METADATA_NAME.databaseEventTrigger - >, - ): FlatEntityValidationReturnType< - typeof ALL_METADATA_NAME.databaseEventTrigger, - 'delete' - > { - const validationResult = - this.flatDatabaseEventTriggerValidatorService.validateFlatDatabaseEventTriggerDeletion( - args, - ); - - if (validationResult.errors.length > 0) { - return { - status: 'fail', - ...validationResult, - }; - } - - const { flatEntityToValidate: flatDatabaseEventTriggerToValidate } = args; - - return { - status: 'success', - action: { - type: 'delete', - metadataName: 'databaseEventTrigger', - universalIdentifier: - flatDatabaseEventTriggerToValidate.universalIdentifier, - }, - }; - } - - protected validateFlatEntityUpdate( - args: FlatEntityUpdateValidationArgs< - typeof ALL_METADATA_NAME.databaseEventTrigger - >, - ): FlatEntityValidationReturnType< - typeof ALL_METADATA_NAME.databaseEventTrigger, - 'update' - > { - const validationResult = - this.flatDatabaseEventTriggerValidatorService.validateFlatDatabaseEventTriggerUpdate( - args, - ); - - if (validationResult.errors.length > 0) { - return { - status: 'fail', - ...validationResult, - }; - } - - const { flatEntityId, flatEntityUpdates } = args; - - const updateDatabaseEventTriggerAction: UpdateDatabaseEventTriggerAction = { - type: 'update', - metadataName: 'databaseEventTrigger', - entityId: flatEntityId, - updates: flatEntityUpdates, - }; - - return { - status: 'success', - action: updateDatabaseEventTriggerAction, - }; - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/types/workspace-migration-route-trigger-action.type.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/types/workspace-migration-route-trigger-action.type.ts deleted file mode 100644 index 481db92da7..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/types/workspace-migration-route-trigger-action.type.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { type BaseCreateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-create-workspace-migration-action.type'; -import { type BaseDeleteWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-delete-workspace-migration-action.type'; -import { type BaseUpdateWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/base-update-workspace-migration-action.type'; - -export type CreateRouteTriggerAction = - BaseCreateWorkspaceMigrationAction<'routeTrigger'>; - -export type UpdateRouteTriggerAction = - BaseUpdateWorkspaceMigrationAction<'routeTrigger'>; - -export type DeleteRouteTriggerAction = - BaseDeleteWorkspaceMigrationAction<'routeTrigger'>; diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/workspace-migration-route-trigger-actions-builder.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/workspace-migration-route-trigger-actions-builder.service.ts deleted file mode 100644 index 5603d3b3d1..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/workspace-migration-route-trigger-actions-builder.service.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { ALL_METADATA_NAME } from 'twenty-shared/metadata'; - -import { UpdateRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/types/workspace-migration-route-trigger-action.type'; -import { WorkspaceEntityMigrationBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/services/workspace-entity-migration-builder.service'; -import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type'; -import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type'; -import { FlatEntityValidationReturnType } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-result.type'; -import { FlatRouteTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-route-trigger-validator.service'; - -@Injectable() -export class WorkspaceMigrationRouteTriggerActionsBuilderService extends WorkspaceEntityMigrationBuilderService< - typeof ALL_METADATA_NAME.routeTrigger -> { - constructor( - private readonly flatRouteTriggerValidatorService: FlatRouteTriggerValidatorService, - ) { - super(ALL_METADATA_NAME.routeTrigger); - } - - protected validateFlatEntityCreation( - args: FlatEntityValidationArgs, - ): FlatEntityValidationReturnType< - typeof ALL_METADATA_NAME.routeTrigger, - 'create' - > { - const validationResult = - this.flatRouteTriggerValidatorService.validateFlatRouteTriggerCreation( - args, - ); - - if (validationResult.errors.length > 0) { - return { - status: 'fail', - ...validationResult, - }; - } - - const { flatEntityToValidate: flatRouteTriggerToValidate } = args; - - return { - status: 'success', - action: { - type: 'create', - metadataName: 'routeTrigger', - flatEntity: flatRouteTriggerToValidate, - }, - }; - } - - protected validateFlatEntityDeletion( - args: FlatEntityValidationArgs, - ): FlatEntityValidationReturnType< - typeof ALL_METADATA_NAME.routeTrigger, - 'delete' - > { - const validationResult = - this.flatRouteTriggerValidatorService.validateFlatRouteTriggerDeletion( - args, - ); - - if (validationResult.errors.length > 0) { - return { - status: 'fail', - ...validationResult, - }; - } - - const { flatEntityToValidate: flatRouteTriggerToValidate } = args; - - return { - status: 'success', - action: { - type: 'delete', - metadataName: 'routeTrigger', - universalIdentifier: flatRouteTriggerToValidate.universalIdentifier, - }, - }; - } - - protected validateFlatEntityUpdate( - args: FlatEntityUpdateValidationArgs, - ): FlatEntityValidationReturnType< - typeof ALL_METADATA_NAME.routeTrigger, - 'update' - > { - const validationResult = - this.flatRouteTriggerValidatorService.validateFlatRouteTriggerUpdate( - args, - ); - - if (validationResult.errors.length > 0) { - return { - status: 'fail', - ...validationResult, - }; - } - - const { flatEntityId, flatEntityUpdates } = args; - - const updateRouteTriggerAction: UpdateRouteTriggerAction = { - type: 'update', - metadataName: 'routeTrigger', - entityId: flatEntityId, - updates: flatEntityUpdates, - }; - - return { - status: 'success', - action: updateRouteTriggerAction, - }; - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-cron-trigger-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-cron-trigger-validator.service.ts deleted file mode 100644 index 7274992211..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-cron-trigger-validator.service.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { msg, t } from '@lingui/core/macro'; -import { ALL_METADATA_NAME } from 'twenty-shared/metadata'; -import { isDefined } from 'twenty-shared/utils'; - -import { CronTriggerExceptionCode } from 'src/engine/metadata-modules/cron-trigger/exceptions/cron-trigger.exception'; -import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type'; -import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util'; -import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type'; -import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type'; -import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity'; - -@Injectable() -export class FlatCronTriggerValidatorService { - constructor() {} - - public validateFlatCronTriggerUpdate({ - flatEntityId, - flatEntityUpdates, - optimisticFlatEntityMapsAndRelatedFlatEntityMaps: { - flatCronTriggerMaps: optimisticFlatCronTriggerMaps, - flatServerlessFunctionMaps, - }, - }: FlatEntityUpdateValidationArgs< - typeof ALL_METADATA_NAME.cronTrigger - >): FailedFlatEntityValidation<'cronTrigger', 'update'> { - const existingFlatCronTrigger = - optimisticFlatCronTriggerMaps.byId[flatEntityId]; - - const validationResult = getEmptyFlatEntityValidationError({ - flatEntityMinimalInformation: { - id: flatEntityId, - universalIdentifier: existingFlatCronTrigger?.universalIdentifier, - }, - metadataName: 'cronTrigger', - type: 'update', - }); - - if (!isDefined(existingFlatCronTrigger)) { - validationResult.errors.push({ - code: CronTriggerExceptionCode.CRON_TRIGGER_NOT_FOUND, - message: t`Cron trigger not found`, - userFriendlyMessage: msg`Cron trigger not found`, - }); - - return validationResult; - } - - const updatedFlatCronTrigger = { - ...existingFlatCronTrigger, - ...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({ - updates: flatEntityUpdates, - }), - }; - - const serverlessFunction = - flatServerlessFunctionMaps.byId[ - updatedFlatCronTrigger.serverlessFunctionId - ]; - - if (!isDefined(serverlessFunction)) { - validationResult.errors.push({ - code: CronTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, - message: t`Serverless function not found`, - userFriendlyMessage: msg`Serverless function not found`, - }); - } - - return validationResult; - } - - public validateFlatCronTriggerDeletion({ - flatEntityToValidate: { id: cronTriggerIdToDelete, universalIdentifier }, - optimisticFlatEntityMapsAndRelatedFlatEntityMaps: { - flatCronTriggerMaps: optimisticFlatCronTriggerMaps, - }, - }: FlatEntityValidationArgs< - typeof ALL_METADATA_NAME.cronTrigger - >): FailedFlatEntityValidation<'cronTrigger', 'delete'> { - const validationResult = getEmptyFlatEntityValidationError({ - flatEntityMinimalInformation: { - id: cronTriggerIdToDelete, - universalIdentifier, - }, - metadataName: 'cronTrigger', - type: 'delete', - }); - - const existingFlatCronTrigger = - optimisticFlatCronTriggerMaps.byId[cronTriggerIdToDelete]; - - if (!isDefined(existingFlatCronTrigger)) { - validationResult.errors.push({ - code: CronTriggerExceptionCode.CRON_TRIGGER_NOT_FOUND, - message: t`Cron trigger not found`, - userFriendlyMessage: msg`Cron trigger not found`, - }); - } - - return validationResult; - } - - public validateFlatCronTriggerCreation({ - flatEntityToValidate: flatCronTriggerToValidate, - optimisticFlatEntityMapsAndRelatedFlatEntityMaps: { - flatCronTriggerMaps: optimisticFlatCronTriggerMaps, - flatServerlessFunctionMaps, - }, - }: FlatEntityValidationArgs< - typeof ALL_METADATA_NAME.cronTrigger - >): FailedFlatEntityValidation<'cronTrigger', 'create'> { - const validationResult = getEmptyFlatEntityValidationError({ - flatEntityMinimalInformation: { - id: flatCronTriggerToValidate.id, - universalIdentifier: flatCronTriggerToValidate.universalIdentifier, - }, - metadataName: 'cronTrigger', - type: 'create', - }); - - if ( - isDefined( - optimisticFlatCronTriggerMaps.byId[flatCronTriggerToValidate.id], - ) - ) { - validationResult.errors.push({ - code: CronTriggerExceptionCode.CRON_TRIGGER_ALREADY_EXIST, - message: t`Cron trigger with same id already exists`, - userFriendlyMessage: msg`Cron trigger already exists`, - }); - } - - const serverlessFunction = - flatServerlessFunctionMaps.byId[ - flatCronTriggerToValidate.serverlessFunctionId - ]; - - if (!isDefined(serverlessFunction)) { - validationResult.errors.push({ - code: CronTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, - message: t`Serverless function not found`, - userFriendlyMessage: msg`Serverless function not found`, - }); - } - - return validationResult; - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-database-event-trigger-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-database-event-trigger-validator.service.ts deleted file mode 100644 index c286950e73..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-database-event-trigger-validator.service.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { msg, t } from '@lingui/core/macro'; -import { ALL_METADATA_NAME } from 'twenty-shared/metadata'; -import { isDefined } from 'twenty-shared/utils'; - -import { DatabaseEventTriggerExceptionCode } from 'src/engine/metadata-modules/database-event-trigger/exceptions/database-event-trigger.exception'; -import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type'; -import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util'; -import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type'; -import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type'; -import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity'; - -// TODO: validate settings integrity -@Injectable() -export class FlatDatabaseEventTriggerValidatorService { - constructor() {} - - public validateFlatDatabaseEventTriggerUpdate({ - flatEntityId, - flatEntityUpdates, - optimisticFlatEntityMapsAndRelatedFlatEntityMaps: { - flatDatabaseEventTriggerMaps: optimisticFlatDatabaseEventTriggerMaps, - flatServerlessFunctionMaps, - }, - }: FlatEntityUpdateValidationArgs< - typeof ALL_METADATA_NAME.databaseEventTrigger - >): FailedFlatEntityValidation<'databaseEventTrigger', 'update'> { - const existingFlatDatabaseEventTrigger = - optimisticFlatDatabaseEventTriggerMaps.byId[flatEntityId]; - - const validationResult = getEmptyFlatEntityValidationError({ - flatEntityMinimalInformation: { - id: flatEntityId, - universalIdentifier: - existingFlatDatabaseEventTrigger?.universalIdentifier, - }, - metadataName: 'databaseEventTrigger', - type: 'update', - }); - - if (!isDefined(existingFlatDatabaseEventTrigger)) { - validationResult.errors.push({ - code: DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_NOT_FOUND, - message: t`Database event trigger not found`, - userFriendlyMessage: msg`Database event trigger not found`, - }); - - return validationResult; - } - - const updatedFlatDatabaseEventTrigger = { - ...existingFlatDatabaseEventTrigger, - ...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({ - updates: flatEntityUpdates, - }), - }; - - const serverlessFunction = - flatServerlessFunctionMaps.byId[ - updatedFlatDatabaseEventTrigger.serverlessFunctionId - ]; - - if (!isDefined(serverlessFunction)) { - validationResult.errors.push({ - code: DatabaseEventTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, - message: t`Serverless function not found`, - userFriendlyMessage: msg`Serverless function not found`, - }); - } - - return validationResult; - } - - public validateFlatDatabaseEventTriggerDeletion({ - flatEntityToValidate: { - id: databaseEventTriggerIdToDelete, - universalIdentifier, - }, - optimisticFlatEntityMapsAndRelatedFlatEntityMaps: { - flatDatabaseEventTriggerMaps: optimisticFlatDatabaseEventTriggerMaps, - }, - }: FlatEntityValidationArgs< - typeof ALL_METADATA_NAME.databaseEventTrigger - >): FailedFlatEntityValidation<'databaseEventTrigger', 'delete'> { - const validationResult = getEmptyFlatEntityValidationError({ - flatEntityMinimalInformation: { - id: databaseEventTriggerIdToDelete, - universalIdentifier, - }, - metadataName: 'databaseEventTrigger', - type: 'delete', - }); - - const existingFlatDatabaseEventTrigger = - optimisticFlatDatabaseEventTriggerMaps.byId[ - databaseEventTriggerIdToDelete - ]; - - if (!isDefined(existingFlatDatabaseEventTrigger)) { - validationResult.errors.push({ - code: DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_NOT_FOUND, - message: t`Database event trigger not found`, - userFriendlyMessage: msg`Database event trigger not found`, - }); - } - - return validationResult; - } - - public validateFlatDatabaseEventTriggerCreation({ - flatEntityToValidate: flatDatabaseEventTriggerToValidate, - optimisticFlatEntityMapsAndRelatedFlatEntityMaps: { - flatDatabaseEventTriggerMaps: optimisticFlatDatabaseEventTriggerMaps, - flatServerlessFunctionMaps, - }, - }: FlatEntityValidationArgs< - typeof ALL_METADATA_NAME.databaseEventTrigger - >): FailedFlatEntityValidation<'databaseEventTrigger', 'create'> { - const validationResult = getEmptyFlatEntityValidationError({ - flatEntityMinimalInformation: { - id: flatDatabaseEventTriggerToValidate.id, - universalIdentifier: - flatDatabaseEventTriggerToValidate.universalIdentifier, - }, - metadataName: 'databaseEventTrigger', - type: 'create', - }); - - if ( - isDefined( - optimisticFlatDatabaseEventTriggerMaps.byId[ - flatDatabaseEventTriggerToValidate.id - ], - ) - ) { - validationResult.errors.push({ - code: DatabaseEventTriggerExceptionCode.DATABASE_EVENT_TRIGGER_ALREADY_EXIST, - message: t`Database event trigger with same id already exists`, - userFriendlyMessage: msg`Database event trigger already exists`, - }); - } - - const serverlessFunction = - flatServerlessFunctionMaps?.byId?.[ - flatDatabaseEventTriggerToValidate.serverlessFunctionId - ]; - - if (!isDefined(serverlessFunction)) { - validationResult.errors.push({ - code: DatabaseEventTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, - message: t`Serverless function not found`, - userFriendlyMessage: msg`Serverless function not found`, - }); - } - - return validationResult; - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-route-trigger-validator.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-route-trigger-validator.service.ts deleted file mode 100644 index 06d44f2498..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-route-trigger-validator.service.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { msg, t } from '@lingui/core/macro'; -import { ALL_METADATA_NAME } from 'twenty-shared/metadata'; -import { isDefined } from 'twenty-shared/utils'; - -import { RouteTriggerExceptionCode } from 'src/engine/metadata-modules/route-trigger/exceptions/route-trigger.exception'; -import { FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type'; -import { getEmptyFlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/utils/get-flat-entity-validation-error.util'; -import { FlatEntityUpdateValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-update-validation-args.type'; -import { FlatEntityValidationArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/flat-entity-validation-args.type'; -import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity'; - -@Injectable() -export class FlatRouteTriggerValidatorService { - constructor() {} - - public validateFlatRouteTriggerUpdate({ - flatEntityId, - flatEntityUpdates, - optimisticFlatEntityMapsAndRelatedFlatEntityMaps: { - flatRouteTriggerMaps: optimisticFlatRouteTriggerMaps, - flatServerlessFunctionMaps, - }, - }: FlatEntityUpdateValidationArgs< - typeof ALL_METADATA_NAME.routeTrigger - >): FailedFlatEntityValidation<'routeTrigger', 'update'> { - const existingFlatRouteTrigger = - optimisticFlatRouteTriggerMaps.byId[flatEntityId]; - - const validationResult = getEmptyFlatEntityValidationError({ - flatEntityMinimalInformation: { - id: flatEntityId, - universalIdentifier: existingFlatRouteTrigger?.universalIdentifier, - }, - metadataName: 'routeTrigger', - type: 'update', - }); - - if (!isDefined(existingFlatRouteTrigger)) { - validationResult.errors.push({ - code: RouteTriggerExceptionCode.ROUTE_NOT_FOUND, - message: t`Route not found`, - userFriendlyMessage: msg`Route not found`, - }); - - return validationResult; - } - - const updatedFlatRouteTrigger = { - ...existingFlatRouteTrigger, - ...fromFlatEntityPropertiesUpdatesToPartialFlatEntity({ - updates: flatEntityUpdates, - }), - }; - - const serverlessFunction = - flatServerlessFunctionMaps.byId[ - updatedFlatRouteTrigger.serverlessFunctionId - ]; - - if (!isDefined(serverlessFunction)) { - validationResult.errors.push({ - code: RouteTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, - message: t`Serverless function not found`, - userFriendlyMessage: msg`Serverless function not found`, - }); - } - - return validationResult; - } - - public validateFlatRouteTriggerDeletion({ - flatEntityToValidate: { id: routeTriggerIdToDelete, universalIdentifier }, - optimisticFlatEntityMapsAndRelatedFlatEntityMaps: { - flatRouteTriggerMaps: optimisticFlatRouteTriggerMaps, - }, - }: FlatEntityValidationArgs< - typeof ALL_METADATA_NAME.routeTrigger - >): FailedFlatEntityValidation<'routeTrigger', 'delete'> { - const validationResult = getEmptyFlatEntityValidationError({ - flatEntityMinimalInformation: { - id: routeTriggerIdToDelete, - universalIdentifier, - }, - metadataName: 'routeTrigger', - type: 'delete', - }); - - const existingFlatRouteTrigger = - optimisticFlatRouteTriggerMaps.byId[routeTriggerIdToDelete]; - - if (!isDefined(existingFlatRouteTrigger)) { - validationResult.errors.push({ - code: RouteTriggerExceptionCode.ROUTE_NOT_FOUND, - message: t`Route not found`, - userFriendlyMessage: msg`Route not found`, - }); - } - - return validationResult; - } - - public validateFlatRouteTriggerCreation({ - flatEntityToValidate: flatRouteTriggerToValidate, - optimisticFlatEntityMapsAndRelatedFlatEntityMaps: { - flatRouteTriggerMaps: optimisticFlatRouteTriggerMaps, - flatServerlessFunctionMaps, - }, - }: FlatEntityValidationArgs< - typeof ALL_METADATA_NAME.routeTrigger - >): FailedFlatEntityValidation<'routeTrigger', 'create'> { - const validationResult = getEmptyFlatEntityValidationError({ - flatEntityMinimalInformation: { - id: flatRouteTriggerToValidate.id, - universalIdentifier: flatRouteTriggerToValidate.universalIdentifier, - }, - metadataName: 'routeTrigger', - type: 'create', - }); - - if ( - isDefined( - optimisticFlatRouteTriggerMaps.byId[flatRouteTriggerToValidate.id], - ) - ) { - validationResult.errors.push({ - code: RouteTriggerExceptionCode.ROUTE_ALREADY_EXIST, - message: t`Route with same id already exists`, - userFriendlyMessage: msg`Route already exists`, - }); - } - - const existingFlatRouteTriggers = Object.values( - optimisticFlatRouteTriggerMaps.byId, - ).filter(isDefined); - - if ( - existingFlatRouteTriggers.find( - (flatRouteTrigger) => - flatRouteTrigger.path === flatRouteTriggerToValidate.path, - ) - ) { - validationResult.errors.push({ - code: RouteTriggerExceptionCode.ROUTE_PATH_ALREADY_EXIST, - message: t`Route with same path already exists`, - userFriendlyMessage: msg`Route path already exists`, - }); - } - - const serverlessFunction = - flatServerlessFunctionMaps.byId[ - flatRouteTriggerToValidate.serverlessFunctionId - ]; - - if (!isDefined(serverlessFunction)) { - validationResult.errors.push({ - code: RouteTriggerExceptionCode.SERVERLESS_FUNCTION_NOT_FOUND, - message: t`Serverless function not found`, - userFriendlyMessage: msg`Serverless function not found`, - }); - } - - return validationResult; - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/workspace-migration-builder-validators.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/workspace-migration-builder-validators.module.ts index 3ed5426a85..b5d18c7724 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/workspace-migration-builder-validators.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/workspace-migration-builder-validators.module.ts @@ -5,8 +5,6 @@ import { FlatFieldMetadataTypeValidatorService } from 'src/engine/metadata-modul import { FlatPageLayoutWidgetTypeValidatorService } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service'; import { FlatAgentValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-agent-validator.service'; import { FlatCommandMenuItemValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-command-menu-item-validator.service'; -import { FlatCronTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-cron-trigger-validator.service'; -import { FlatDatabaseEventTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-database-event-trigger-validator.service'; import { FlatFieldMetadataValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-field-metadata-validator.service'; import { FlatFrontComponentValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-front-component-validator.service'; import { FlatIndexValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-index-metadata-validator.service'; @@ -17,7 +15,6 @@ import { FlatPageLayoutValidatorService } from 'src/engine/workspace-manager/wor import { FlatPageLayoutWidgetValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-page-layout-widget-validator.service'; import { FlatRoleTargetValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-target-validator.service'; import { FlatRoleValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-role-validator.service'; -import { FlatRouteTriggerValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-route-trigger-validator.service'; import { FlatRowLevelPermissionPredicateGroupValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-group-validator.service'; import { FlatRowLevelPermissionPredicateValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-row-level-permission-predicate-validator.service'; import { FlatServerlessFunctionValidatorService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/validators/services/flat-serverless-function-validator.service'; @@ -41,11 +38,8 @@ import { FlatWebhookValidatorService } from 'src/engine/workspace-manager/worksp FlatFieldMetadataValidatorService, FlatObjectMetadataValidatorService, FlatServerlessFunctionValidatorService, - FlatDatabaseEventTriggerValidatorService, - FlatCronTriggerValidatorService, FlatFieldMetadataTypeValidatorService, FlatPageLayoutWidgetTypeValidatorService, - FlatRouteTriggerValidatorService, FlatRoleValidatorService, FlatRoleTargetValidatorService, FlatAgentValidatorService, @@ -70,10 +64,7 @@ import { FlatWebhookValidatorService } from 'src/engine/workspace-manager/worksp FlatFieldMetadataValidatorService, FlatObjectMetadataValidatorService, FlatServerlessFunctionValidatorService, - FlatDatabaseEventTriggerValidatorService, - FlatCronTriggerValidatorService, FlatFieldMetadataTypeValidatorService, - FlatRouteTriggerValidatorService, FlatRoleValidatorService, FlatRoleTargetValidatorService, FlatAgentValidatorService, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/workspace-migration-builder.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/workspace-migration-builder.module.ts index 152df7c0b3..e3a4938970 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/workspace-migration-builder.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-builder/workspace-migration-builder.module.ts @@ -5,8 +5,6 @@ import { FlatFieldMetadataTypeValidatorService } from 'src/engine/metadata-modul import { WorkspaceMigrationAgentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/workspace-migration-agent-actions-builder.service'; import { WorkspaceMigrationCommandMenuItemActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/command-menu-item/workspace-migration-command-menu-item-actions-builder.service'; import { WorkspaceMigrationNavigationMenuItemActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/navigation-menu-item/workspace-migration-navigation-menu-item-actions-builder.service'; -import { WorkspaceMigrationCronTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/workspace-migration-cron-trigger-action-builder.service'; -import { WorkspaceMigrationDatabaseEventTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/workspace-migration-database-event-trigger-actions-builder.service'; import { WorkspaceMigrationFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/workspace-migration-field-actions-builder.service'; import { WorkspaceMigrationIndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/index/workspace-migration-index-actions-builder.service'; import { WorkspaceMigrationObjectActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/workspace-migration-object-actions-builder.service'; @@ -15,7 +13,6 @@ import { WorkspaceMigrationPageLayoutWidgetActionsBuilderService } from 'src/eng import { WorkspaceMigrationPageLayoutActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/workspace-migration-page-layout-actions-builder.service'; import { WorkspaceMigrationRoleTargetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role-target/workspace-migration-role-target-actions-builder.service'; import { WorkspaceMigrationRoleActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role/workspace-migration-role-actions-builder.service'; -import { WorkspaceMigrationRouteTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/workspace-migration-route-trigger-actions-builder.service'; import { WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate-group/workspace-migration-row-level-permission-predicate-group-actions-builder.service'; import { WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate/workspace-migration-row-level-permission-predicate-actions-builder.service'; import { WorkspaceMigrationServerlessFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/serverless-function/workspace-migration-serverless-function-actions-builder.service'; @@ -41,10 +38,7 @@ import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace- WorkspaceMigrationViewGroupActionsBuilderService, WorkspaceMigrationIndexActionsBuilderService, WorkspaceMigrationServerlessFunctionActionsBuilderService, - WorkspaceMigrationDatabaseEventTriggerActionsBuilderService, WorkspaceMigrationFieldActionsBuilderService, - WorkspaceMigrationCronTriggerActionsBuilderService, - WorkspaceMigrationRouteTriggerActionsBuilderService, WorkspaceMigrationRoleActionsBuilderService, WorkspaceMigrationRoleTargetActionsBuilderService, WorkspaceMigrationAgentActionsBuilderService, @@ -69,9 +63,6 @@ import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace- WorkspaceMigrationViewGroupActionsBuilderService, WorkspaceMigrationFieldActionsBuilderService, WorkspaceMigrationServerlessFunctionActionsBuilderService, - WorkspaceMigrationDatabaseEventTriggerActionsBuilderService, - WorkspaceMigrationCronTriggerActionsBuilderService, - WorkspaceMigrationRouteTriggerActionsBuilderService, WorkspaceMigrationRoleActionsBuilderService, WorkspaceMigrationRoleTargetActionsBuilderService, WorkspaceMigrationAgentActionsBuilderService, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/create-cron-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/create-cron-trigger-action-handler.service.ts deleted file mode 100644 index 45bf58b402..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/create-cron-trigger-action-handler.service.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface'; - -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { CreateCronTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/types/workspace-migration-cron-trigger-action.type'; -import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type'; - -@Injectable() -export class CreateCronTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( - 'create', - 'cronTrigger', -) { - constructor() { - super(); - } - - async executeForMetadata( - context: WorkspaceMigrationActionRunnerArgs, - ): Promise { - const { action, queryRunner, workspaceId } = context; - const { flatEntity: cronTrigger } = action; - - const cronTriggerRepository = - queryRunner.manager.getRepository(CronTriggerEntity); - - await cronTriggerRepository.insert({ - ...cronTrigger, - workspaceId, - }); - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/delete-cron-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/delete-cron-trigger-action-handler.service.ts deleted file mode 100644 index 9481ebb94d..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/delete-cron-trigger-action-handler.service.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface'; - -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util'; -import { DeleteCronTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/types/workspace-migration-cron-trigger-action.type'; -import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type'; - -@Injectable() -export class DeleteCronTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( - 'delete', - 'cronTrigger', -) { - constructor() { - super(); - } - - async executeForMetadata( - context: WorkspaceMigrationActionRunnerArgs, - ): Promise { - const { action, queryRunner, workspaceId, allFlatEntityMaps } = context; - const { universalIdentifier } = action; - - const flatCronTrigger = findFlatEntityByUniversalIdentifierOrThrow({ - flatEntityMaps: allFlatEntityMaps.flatCronTriggerMaps, - universalIdentifier, - }); - - const cronTriggerRepository = - queryRunner.manager.getRepository(CronTriggerEntity); - - await cronTriggerRepository.delete({ - id: flatCronTrigger.id, - workspaceId, - }); - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/update-cron-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/update-cron-trigger-action-handler.service.ts deleted file mode 100644 index b3ac28c07a..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/update-cron-trigger-action-handler.service.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface'; - -import { CronTriggerEntity } from 'src/engine/metadata-modules/cron-trigger/entities/cron-trigger.entity'; -import { UpdateCronTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/types/workspace-migration-cron-trigger-action.type'; -import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type'; -import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity'; - -@Injectable() -export class UpdateCronTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( - 'update', - 'cronTrigger', -) { - constructor() { - super(); - } - - async executeForMetadata( - context: WorkspaceMigrationActionRunnerArgs, - ): Promise { - const { action, queryRunner } = context; - const { entityId } = action; - - const cronTriggerRepository = - queryRunner.manager.getRepository(CronTriggerEntity); - - await cronTriggerRepository.update( - entityId, - fromFlatEntityPropertiesUpdatesToPartialFlatEntity(action), - ); - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/create-database-event-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/create-database-event-trigger-action-handler.service.ts deleted file mode 100644 index 4adbc41f90..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/create-database-event-trigger-action-handler.service.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface'; - -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; -import { CreateDatabaseEventTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/types/workspace-migration-database-event-trigger-action.type'; -import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type'; - -@Injectable() -export class CreateDatabaseEventTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( - 'create', - 'databaseEventTrigger', -) { - constructor() { - super(); - } - - async executeForMetadata( - context: WorkspaceMigrationActionRunnerArgs, - ): Promise { - const { action, queryRunner, workspaceId } = context; - const { flatEntity: databaseEventTrigger } = action; - - const databaseEventTriggerRepository = - queryRunner.manager.getRepository( - DatabaseEventTriggerEntity, - ); - - await databaseEventTriggerRepository.insert({ - ...databaseEventTrigger, - workspaceId, - }); - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/delete-database-event-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/delete-database-event-trigger-action-handler.service.ts deleted file mode 100644 index bfb7b126db..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/delete-database-event-trigger-action-handler.service.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface'; - -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; -import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util'; -import { DeleteDatabaseEventTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/types/workspace-migration-database-event-trigger-action.type'; -import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type'; - -@Injectable() -export class DeleteDatabaseEventTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( - 'delete', - 'databaseEventTrigger', -) { - constructor() { - super(); - } - - async executeForMetadata( - context: WorkspaceMigrationActionRunnerArgs, - ): Promise { - const { action, queryRunner, workspaceId, allFlatEntityMaps } = context; - const { universalIdentifier } = action; - - const flatDatabaseEventTrigger = findFlatEntityByUniversalIdentifierOrThrow( - { - flatEntityMaps: allFlatEntityMaps.flatDatabaseEventTriggerMaps, - universalIdentifier, - }, - ); - - const databaseEventTriggerRepository = - queryRunner.manager.getRepository( - DatabaseEventTriggerEntity, - ); - - await databaseEventTriggerRepository.delete({ - id: flatDatabaseEventTrigger.id, - workspaceId, - }); - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/update-database-event-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/update-database-event-trigger-action-handler.service.ts deleted file mode 100644 index 94ee8020aa..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/update-database-event-trigger-action-handler.service.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface'; - -import { DatabaseEventTriggerEntity } from 'src/engine/metadata-modules/database-event-trigger/entities/database-event-trigger.entity'; -import { UpdateDatabaseEventTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/types/workspace-migration-database-event-trigger-action.type'; -import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type'; -import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity'; - -@Injectable() -export class UpdateDatabaseEventTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( - 'update', - 'databaseEventTrigger', -) { - constructor() { - super(); - } - - async executeForMetadata( - context: WorkspaceMigrationActionRunnerArgs, - ): Promise { - const { action, queryRunner } = context; - const { entityId } = action; - - const databaseEventTriggerRepository = - queryRunner.manager.getRepository( - DatabaseEventTriggerEntity, - ); - - await databaseEventTriggerRepository.update( - entityId, - fromFlatEntityPropertiesUpdatesToPartialFlatEntity(action), - ); - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/create-route-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/create-route-trigger-action-handler.service.ts deleted file mode 100644 index ffb4823e03..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/create-route-trigger-action-handler.service.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface'; - -import { RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; -import { CreateRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/types/workspace-migration-route-trigger-action.type'; -import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type'; - -@Injectable() -export class CreateRouteTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( - 'create', - 'routeTrigger', -) { - constructor() { - super(); - } - - async executeForMetadata( - context: WorkspaceMigrationActionRunnerArgs, - ): Promise { - const { action, queryRunner, workspaceId } = context; - const { flatEntity: routeTrigger } = action; - - const routeTriggerRepository = - queryRunner.manager.getRepository(RouteTriggerEntity); - - await routeTriggerRepository.insert({ - ...routeTrigger, - workspaceId, - }); - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service.ts deleted file mode 100644 index a3887f787e..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface'; - -import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util'; -import { RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; -import { DeleteRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/types/workspace-migration-route-trigger-action.type'; -import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type'; - -@Injectable() -export class DeleteRouteTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( - 'delete', - 'routeTrigger', -) { - constructor() { - super(); - } - - async executeForMetadata( - context: WorkspaceMigrationActionRunnerArgs, - ): Promise { - const { action, queryRunner, workspaceId, allFlatEntityMaps } = context; - const { universalIdentifier } = action; - - const flatRouteTrigger = findFlatEntityByUniversalIdentifierOrThrow({ - flatEntityMaps: allFlatEntityMaps.flatRouteTriggerMaps, - universalIdentifier, - }); - - const routeTriggerRepository = - queryRunner.manager.getRepository(RouteTriggerEntity); - - await routeTriggerRepository.delete({ - id: flatRouteTrigger.id, - workspaceId, - }); - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/update-route-trigger-action-handler.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/update-route-trigger-action-handler.service.ts deleted file mode 100644 index a9ad7a4701..0000000000 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/update-route-trigger-action-handler.service.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface'; - -import { RouteTriggerEntity } from 'src/engine/metadata-modules/route-trigger/route-trigger.entity'; -import { UpdateRouteTriggerAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/types/workspace-migration-route-trigger-action.type'; -import { WorkspaceMigrationActionRunnerArgs } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/types/workspace-migration-action-runner-args.type'; -import { fromFlatEntityPropertiesUpdatesToPartialFlatEntity } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/from-flat-entity-properties-updates-to-partial-flat-entity'; - -@Injectable() -export class UpdateRouteTriggerActionHandlerService extends WorkspaceMigrationRunnerActionHandler( - 'update', - 'routeTrigger', -) { - constructor() { - super(); - } - - async executeForMetadata( - context: WorkspaceMigrationActionRunnerArgs, - ): Promise { - const { action, queryRunner } = context; - const { entityId } = action; - - const routeTriggerRepository = - queryRunner.manager.getRepository(RouteTriggerEntity); - - await routeTriggerRepository.update( - entityId, - fromFlatEntityPropertiesUpdatesToPartialFlatEntity(action), - ); - } -} diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts index a7f5e3a877..987d0122f8 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/workspace-schema-migration-runner-action-handlers.module.ts @@ -10,12 +10,6 @@ import { UpdateCommandMenuItemActionHandlerService } from 'src/engine/workspace- import { CreateNavigationMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/navigation-menu-item/services/create-navigation-menu-item-action-handler.service'; import { DeleteNavigationMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/navigation-menu-item/services/delete-navigation-menu-item-action-handler.service'; import { UpdateNavigationMenuItemActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/navigation-menu-item/services/update-navigation-menu-item-action-handler.service'; -import { CreateCronTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/create-cron-trigger-action-handler.service'; -import { DeleteCronTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/delete-cron-trigger-action-handler.service'; -import { UpdateCronTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/cron-trigger/services/update-cron-trigger-action-handler.service'; -import { CreateDatabaseEventTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/create-database-event-trigger-action-handler.service'; -import { DeleteDatabaseEventTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/delete-database-event-trigger-action-handler.service'; -import { UpdateDatabaseEventTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/database-event-trigger/services/update-database-event-trigger-action-handler.service'; import { CreateFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/create-field-action-handler.service'; import { DeleteFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/delete-field-action-handler.service'; import { UpdateFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/field/services/update-field-action-handler.service'; @@ -40,9 +34,6 @@ import { UpdateRoleTargetActionHandlerService } from 'src/engine/workspace-manag import { CreateRoleActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/role/services/create-role-action-handler.service'; import { DeleteRoleActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/role/services/delete-role-action-handler.service'; import { UpdateRoleActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/role/services/update-role-action-handler.service'; -import { CreateRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/create-route-trigger-action-handler.service'; -import { DeleteRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service'; -import { UpdateRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/route-trigger/services/update-route-trigger-action-handler.service'; import { CreateRowLevelPermissionPredicateGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/row-level-permission-predicate-group/services/create-row-level-permission-predicate-group-action-handler.service'; import { DeleteRowLevelPermissionPredicateGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/row-level-permission-predicate-group/services/delete-row-level-permission-predicate-group-action-handler.service'; import { UpdateRowLevelPermissionPredicateGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/row-level-permission-predicate-group/services/update-row-level-permission-predicate-group-action-handler.service'; @@ -117,18 +108,6 @@ import { FunctionBuildModule } from 'src/engine/metadata-modules/function-build/ DeleteServerlessFunctionActionHandlerService, UpdateServerlessFunctionActionHandlerService, - CreateDatabaseEventTriggerActionHandlerService, - DeleteDatabaseEventTriggerActionHandlerService, - UpdateDatabaseEventTriggerActionHandlerService, - - CreateCronTriggerActionHandlerService, - DeleteCronTriggerActionHandlerService, - UpdateCronTriggerActionHandlerService, - - CreateRouteTriggerActionHandlerService, - DeleteRouteTriggerActionHandlerService, - UpdateRouteTriggerActionHandlerService, - CreateRoleActionHandlerService, UpdateRoleActionHandlerService, DeleteRoleActionHandlerService, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-create-action-on-all-flat-entity-maps.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-create-action-on-all-flat-entity-maps.util.ts index 4222fe9e6a..8b70fef418 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-create-action-on-all-flat-entity-maps.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-create-action-on-all-flat-entity-maps.util.ts @@ -59,9 +59,6 @@ export const optimisticallyApplyCreateActionOnAllFlatEntityMaps = < case 'viewFilterGroup': case 'index': case 'serverlessFunction': - case 'cronTrigger': - case 'databaseEventTrigger': - case 'routeTrigger': case 'viewFilter': case 'role': case 'roleTarget': diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-delete-action-on-all-flat-entity-maps.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-delete-action-on-all-flat-entity-maps.util.ts index 1898bf2b69..70eba57d88 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-delete-action-on-all-flat-entity-maps.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-delete-action-on-all-flat-entity-maps.util.ts @@ -36,9 +36,6 @@ export const optimisticallyApplyDeleteActionOnAllFlatEntityMaps = < case 'viewFilterGroup': case 'index': case 'serverlessFunction': - case 'cronTrigger': - case 'databaseEventTrigger': - case 'routeTrigger': case 'viewFilter': case 'role': case 'roleTarget': diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-update-action-on-all-flat-entity-maps.util.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-update-action-on-all-flat-entity-maps.util.ts index 9e3286b4ff..f751911ebe 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-update-action-on-all-flat-entity-maps.util.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/utils/optimistically-apply-update-action-on-all-flat-entity-maps.util.ts @@ -58,9 +58,6 @@ export const optimisticallyApplyUpdateActionOnAllFlatEntityMaps = < case 'rowLevelPermissionPredicateGroup': case 'viewFilterGroup': case 'serverlessFunction': - case 'cronTrigger': - case 'databaseEventTrigger': - case 'routeTrigger': case 'viewFilter': case 'role': case 'roleTarget': diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/__tests__/workflow-version-step-operations.workspace-service.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/__tests__/workflow-version-step-operations.workspace-service.spec.ts index 915d7d107c..ca7ce9d6ff 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/__tests__/workflow-version-step-operations.workspace-service.spec.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/__tests__/workflow-version-step-operations.workspace-service.spec.ts @@ -260,9 +260,9 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => { serverlessFunctionLayerId: 'layer-id', universalIdentifier: 'universal-id', applicationId: 'application-id', - cronTriggerIds: [], - databaseEventTriggerIds: [], - routeTriggerIds: [], + cronTriggerSettings: null, + databaseEventTriggerSettings: null, + httpRouteTriggerSettings: null, }; serverlessFunctionService.createOneServerlessFunction.mockResolvedValue( @@ -340,9 +340,9 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => { serverlessFunctionLayerId: 'layer-id', universalIdentifier: 'universal-id', applicationId: 'application-id', - cronTriggerIds: [], - databaseEventTriggerIds: [], - routeTriggerIds: [], + cronTriggerSettings: null, + databaseEventTriggerSettings: null, + httpRouteTriggerSettings: null, }; serverlessFunctionService.duplicateServerlessFunction.mockResolvedValue( diff --git a/packages/twenty-server/test/integration/graphql/suites/workspace/successful-user-and-workspace-creation.integration-spec.ts b/packages/twenty-server/test/integration/graphql/suites/workspace/successful-user-and-workspace-creation.integration-spec.ts index 0e2c9a021a..48fa98aa20 100644 --- a/packages/twenty-server/test/integration/graphql/suites/workspace/successful-user-and-workspace-creation.integration-spec.ts +++ b/packages/twenty-server/test/integration/graphql/suites/workspace/successful-user-and-workspace-creation.integration-spec.ts @@ -8,12 +8,8 @@ import { getCurrentUser } from 'test/integration/graphql/utils/get-current-user. import { signUpInNewWorkspace } from 'test/integration/graphql/utils/sign-up-in-new-workspace.util'; import { signUp } from 'test/integration/graphql/utils/sign-up.util'; import { createOneObjectMetadata } from 'test/integration/metadata/suites/object-metadata/utils/create-one-object-metadata.util'; -import { createOneCronTrigger } from 'test/integration/metadata/suites/serverless-function/utils/create-one-cron-trigger.util'; -import { createOneDatabaseEventTrigger } from 'test/integration/metadata/suites/serverless-function/utils/create-one-database-event-trigger.util'; -import { createOneRouteTrigger } from 'test/integration/metadata/suites/serverless-function/utils/create-one-route-trigger.util'; import { createOneServerlessFunction } from 'test/integration/metadata/suites/serverless-function/utils/create-one-serverless-function.util'; import { jestExpectToBeDefined } from 'test/utils/jest-expect-to-be-defined.util.test'; -import { HTTPMethod } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; @@ -193,10 +189,8 @@ describe('Successful user and workspace creation', () => { expectToFail: false, }); - // Create a serverless function with route, cron, and database event triggers - const { - data: { createOneServerlessFunction: serverlessFunction }, - } = await createOneServerlessFunction({ + // Create a serverless function for workspace deletion test + await createOneServerlessFunction({ input: { name: 'test-function-for-deletion', description: 'A test serverless function for workspace deletion test', @@ -205,43 +199,6 @@ describe('Successful user and workspace creation', () => { expectToFail: false, }); - // Create a route trigger for the serverless function - await createOneRouteTrigger({ - input: { - path: '/test-route-for-deletion', - isAuthRequired: true, - httpMethod: HTTPMethod.GET, - serverlessFunctionId: serverlessFunction.id, - forwardedRequestHeaders: [], - }, - token: newWorkspaceAccessToken, - expectToFail: false, - }); - - // Create a cron trigger for the serverless function - await createOneCronTrigger({ - input: { - settings: { - pattern: '0 0 * * *', - }, - serverlessFunctionId: serverlessFunction.id, - }, - token: newWorkspaceAccessToken, - expectToFail: false, - }); - - // Create a database event trigger for the serverless function - await createOneDatabaseEventTrigger({ - input: { - settings: { - eventName: 'company.created', - }, - serverlessFunctionId: serverlessFunction.id, - }, - token: newWorkspaceAccessToken, - expectToFail: false, - }); - const workspaceBeforeDeletion = await testDataSource.query( 'SELECT * FROM core.workspace WHERE id = $1', [workspaceId], @@ -263,15 +220,12 @@ describe('Successful user and workspace creation', () => { 'serverlessFunction', 'serverlessFunctionLayer', 'agent', - 'databaseEventTrigger', 'view', 'viewField', 'viewFilter', 'viewFilterGroup', 'viewGroup', 'viewSort', - 'cronTrigger', - 'routeTrigger', ]; let totalRecordsBefore = 0; diff --git a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-cron-trigger-query-factory.util.ts b/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-cron-trigger-query-factory.util.ts deleted file mode 100644 index 07de1b997b..0000000000 --- a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-cron-trigger-query-factory.util.ts +++ /dev/null @@ -1,27 +0,0 @@ -import gql from 'graphql-tag'; -import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type'; - -import { type CreateCronTriggerInput } from 'src/engine/metadata-modules/cron-trigger/dtos/create-cron-trigger.input'; - -export type CreateOneCronTriggerFactoryInput = CreateCronTriggerInput; - -const DEFAULT_CRON_TRIGGER_GQL_FIELDS = ` - id - settings -`; - -export const createOneCronTriggerQueryFactory = ({ - input, - gqlFields = DEFAULT_CRON_TRIGGER_GQL_FIELDS, -}: PerformMetadataQueryParams) => ({ - query: gql` - mutation CreateOneCronTrigger($input: CreateCronTriggerInput!) { - createOneCronTrigger(input: $input) { - ${gqlFields} - } - } - `, - variables: { - input, - }, -}); diff --git a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-cron-trigger.util.ts b/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-cron-trigger.util.ts deleted file mode 100644 index 84349c9d79..0000000000 --- a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-cron-trigger.util.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - type CreateOneCronTriggerFactoryInput, - createOneCronTriggerQueryFactory, -} from 'test/integration/metadata/suites/serverless-function/utils/create-one-cron-trigger-query-factory.util'; -import { makeMetadataAPIRequest } from 'test/integration/metadata/suites/utils/make-metadata-api-request.util'; -import { type CommonResponseBody } from 'test/integration/metadata/types/common-response-body.type'; -import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type'; -import { warnIfErrorButNotExpectedToFail } from 'test/integration/metadata/utils/warn-if-error-but-not-expected-to-fail.util'; -import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util'; - -import { type CronTriggerDTO } from 'src/engine/metadata-modules/cron-trigger/dtos/cron-trigger.dto'; - -export const createOneCronTrigger = async ({ - input, - gqlFields, - expectToFail = false, - token, -}: PerformMetadataQueryParams): CommonResponseBody<{ - createOneCronTrigger: CronTriggerDTO; -}> => { - const graphqlOperation = createOneCronTriggerQueryFactory({ - input, - gqlFields, - }); - - const response = await makeMetadataAPIRequest(graphqlOperation, token); - - if (expectToFail === true) { - warnIfNoErrorButExpectedToFail({ - response, - errorMessage: 'Cron Trigger creation should have failed but did not', - }); - } - - if (expectToFail === false) { - warnIfErrorButNotExpectedToFail({ - response, - errorMessage: 'Cron Trigger creation has failed but should not', - }); - } - - return { data: response.body.data, errors: response.body.errors }; -}; diff --git a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-database-event-trigger-query-factory.util.ts b/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-database-event-trigger-query-factory.util.ts deleted file mode 100644 index 6cfadb3b0e..0000000000 --- a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-database-event-trigger-query-factory.util.ts +++ /dev/null @@ -1,28 +0,0 @@ -import gql from 'graphql-tag'; -import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type'; - -import { type CreateDatabaseEventTriggerInput } from 'src/engine/metadata-modules/database-event-trigger/dtos/create-database-event-trigger.input'; - -export type CreateOneDatabaseEventTriggerFactoryInput = - CreateDatabaseEventTriggerInput; - -const DEFAULT_DATABASE_EVENT_TRIGGER_GQL_FIELDS = ` - id - settings -`; - -export const createOneDatabaseEventTriggerQueryFactory = ({ - input, - gqlFields = DEFAULT_DATABASE_EVENT_TRIGGER_GQL_FIELDS, -}: PerformMetadataQueryParams) => ({ - query: gql` - mutation CreateOneDatabaseEventTrigger($input: CreateDatabaseEventTriggerInput!) { - createOneDatabaseEventTrigger(input: $input) { - ${gqlFields} - } - } - `, - variables: { - input, - }, -}); diff --git a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-database-event-trigger.util.ts b/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-database-event-trigger.util.ts deleted file mode 100644 index b3c6aae4ef..0000000000 --- a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-database-event-trigger.util.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { - type CreateOneDatabaseEventTriggerFactoryInput, - createOneDatabaseEventTriggerQueryFactory, -} from 'test/integration/metadata/suites/serverless-function/utils/create-one-database-event-trigger-query-factory.util'; -import { makeMetadataAPIRequest } from 'test/integration/metadata/suites/utils/make-metadata-api-request.util'; -import { type CommonResponseBody } from 'test/integration/metadata/types/common-response-body.type'; -import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type'; -import { warnIfErrorButNotExpectedToFail } from 'test/integration/metadata/utils/warn-if-error-but-not-expected-to-fail.util'; -import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util'; - -import { type DatabaseEventTriggerDTO } from 'src/engine/metadata-modules/database-event-trigger/dtos/database-event-trigger.dto'; - -export const createOneDatabaseEventTrigger = async ({ - input, - gqlFields, - expectToFail = false, - token, -}: PerformMetadataQueryParams): CommonResponseBody<{ - createOneDatabaseEventTrigger: DatabaseEventTriggerDTO; -}> => { - const graphqlOperation = createOneDatabaseEventTriggerQueryFactory({ - input, - gqlFields, - }); - - const response = await makeMetadataAPIRequest(graphqlOperation, token); - - if (expectToFail === true) { - warnIfNoErrorButExpectedToFail({ - response, - errorMessage: - 'Database Event Trigger creation should have failed but did not', - }); - } - - if (expectToFail === false) { - warnIfErrorButNotExpectedToFail({ - response, - errorMessage: 'Database Event Trigger creation has failed but should not', - }); - } - - return { data: response.body.data, errors: response.body.errors }; -}; diff --git a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-route-trigger-query-factory.util.ts b/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-route-trigger-query-factory.util.ts deleted file mode 100644 index 84f6b8c1d6..0000000000 --- a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-route-trigger-query-factory.util.ts +++ /dev/null @@ -1,29 +0,0 @@ -import gql from 'graphql-tag'; -import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type'; - -import { type CreateRouteTriggerInput } from 'src/engine/metadata-modules/route-trigger/dtos/create-route-trigger.input'; - -export type CreateOneRouteTriggerFactoryInput = CreateRouteTriggerInput; - -const DEFAULT_ROUTE_TRIGGER_GQL_FIELDS = ` - id - path - isAuthRequired - httpMethod -`; - -export const createOneRouteTriggerQueryFactory = ({ - input, - gqlFields = DEFAULT_ROUTE_TRIGGER_GQL_FIELDS, -}: PerformMetadataQueryParams) => ({ - query: gql` - mutation CreateOneRouteTrigger($input: CreateRouteTriggerInput!) { - createOneRouteTrigger(input: $input) { - ${gqlFields} - } - } - `, - variables: { - input, - }, -}); diff --git a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-route-trigger.util.ts b/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-route-trigger.util.ts deleted file mode 100644 index f70d796ff8..0000000000 --- a/packages/twenty-server/test/integration/metadata/suites/serverless-function/utils/create-one-route-trigger.util.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - type CreateOneRouteTriggerFactoryInput, - createOneRouteTriggerQueryFactory, -} from 'test/integration/metadata/suites/serverless-function/utils/create-one-route-trigger-query-factory.util'; -import { makeMetadataAPIRequest } from 'test/integration/metadata/suites/utils/make-metadata-api-request.util'; -import { type CommonResponseBody } from 'test/integration/metadata/types/common-response-body.type'; -import { type PerformMetadataQueryParams } from 'test/integration/metadata/types/perform-metadata-query.type'; -import { warnIfErrorButNotExpectedToFail } from 'test/integration/metadata/utils/warn-if-error-but-not-expected-to-fail.util'; -import { warnIfNoErrorButExpectedToFail } from 'test/integration/metadata/utils/warn-if-no-error-but-expected-to-fail.util'; - -import { type RouteTriggerDTO } from 'src/engine/metadata-modules/route-trigger/dtos/route-trigger.dto'; - -export const createOneRouteTrigger = async ({ - input, - gqlFields, - expectToFail = false, - token, -}: PerformMetadataQueryParams): CommonResponseBody<{ - createOneRouteTrigger: RouteTriggerDTO; -}> => { - const graphqlOperation = createOneRouteTriggerQueryFactory({ - input, - gqlFields, - }); - - const response = await makeMetadataAPIRequest(graphqlOperation, token); - - if (expectToFail === true) { - warnIfNoErrorButExpectedToFail({ - response, - errorMessage: 'Route Trigger creation should have failed but did not', - }); - } - - if (expectToFail === false) { - warnIfErrorButNotExpectedToFail({ - response, - errorMessage: 'Route Trigger creation has failed but should not', - }); - } - - return { data: response.body.data, errors: response.body.errors }; -};