From 48730df0d24ec66a971f570416e41c71e49ffefe Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Wed, 8 Jul 2026 14:50:03 +0200 Subject: [PATCH] feat(workflow): scaffold core workflowVersion entity + trigger cache (phase 0) (#21674) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What **Phase 0 (scaffold)** of migrating `workflowVersion` data to **core**. Gated by `IS_WORKFLOW_VERSION_IN_CORE_ENABLED` with **no behavior change** — nothing reads or writes the new core entity yet. ## Plan `workflowVersion` becomes a thin **workspace shell** over a core entity (the `dashboard`/`pageLayout` pattern), so navigation, the metadata relations, and the record UI keep working while the heavy data (`triggers`, `steps`) lives in core. Trigger dispatch will derive from active core versions via a per-workspace cache, letting us **eliminate** the denormalized `workflowAutomatedTrigger` object. `workflow` and `workflowRun` stay as workspace objects. Phases: **0 — scaffold (this PR)** → A — backfill + dual-write → B — switch reads to core → C — drop the workspace `trigger`/`steps` columns + the `workflowAutomatedTrigger` object. ## Included - **Core `WorkflowVersionEntity`** (`extends WorkspaceRelatedEntity`) — stores version data, with triggers as an **array** (`triggers: WorkflowTrigger[]`), a long-due shape change. Storage only: dispatch reads the primary trigger, so behavior stays single-trigger for now. - **Fast create-table instance command** for `core."workflowVersion"` (v2.19.0). - **`IS_WORKFLOW_VERSION_IN_CORE_ENABLED`** feature flag. - **Per-workspace automated-trigger cache provider** deriving CRON/DATABASE_EVENT dispatch from the active version's trigger — groundwork for removing `workflowAutomatedTrigger`. ## Notes - `WorkspaceRelatedEntity`, **not** `SyncableEntity`: this is user runtime data (like `connectedAccount`/`apiKey`/`file`), not application-manifest metadata. - No frontend behavior; the generated `FeatureFlagKey` enums are updated to include the new flag. --- .../src/metadata/generated/schema.graphql | 1 + .../src/metadata/generated/schema.ts | 5 +- .../src/generated-admin/graphql.ts | 3 +- .../src/generated-metadata/graphql.ts | 3 +- ...0000-create-workflow-version-core-table.ts | 45 ++++++++++++++ ...ore-table-upgrade-command-name.constant.ts | 4 ++ .../instance-commands.constant.ts | 2 + .../entities/workflow-version.entity.ts | 58 +++++++++++++++++++ ...low-automated-trigger-map-cache.service.ts | 47 +++++++++++++++ .../workflow-automated-trigger-maps.type.ts | 13 +++++ ...ated-trigger-from-workflow-version.util.ts | 38 ++++++++++++ .../workflow/workflow-api.module.ts | 2 + .../workflow/workflow-version-core.module.ts | 16 +++++ .../workspace-entity-manager.spec.ts | 1 + .../types/workspace-cache-key.type.ts | 3 + .../twenty-shared/src/types/FeatureFlagKey.ts | 1 + 16 files changed, 238 insertions(+), 4 deletions(-) create mode 100644 packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-instance-command-fast-1783512000000-create-workflow-version-core-table.ts create mode 100644 packages/twenty-server/src/database/commands/upgrade-version-command/2-20/create-workflow-version-core-table-upgrade-command-name.constant.ts create mode 100644 packages/twenty-server/src/engine/core-modules/workflow/entities/workflow-version.entity.ts create mode 100644 packages/twenty-server/src/engine/core-modules/workflow/services/workspace-workflow-automated-trigger-map-cache.service.ts create mode 100644 packages/twenty-server/src/engine/core-modules/workflow/types/workflow-automated-trigger-maps.type.ts create mode 100644 packages/twenty-server/src/engine/core-modules/workflow/utils/compute-automated-trigger-from-workflow-version.util.ts create mode 100644 packages/twenty-server/src/engine/core-modules/workflow/workflow-version-core.module.ts diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql index 1859539512..89b7c6fb52 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql @@ -1758,6 +1758,7 @@ enum FeatureFlagKey { IS_LOGIC_FUNCTION_PREBUILT_MODE_ENABLED IS_SETTINGS_DISCOVERY_HERO_ENABLED IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED + IS_WORKFLOW_VERSION_IN_CORE_ENABLED } type WorkspaceUrls { diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts index 233f977f5f..7f753e5233 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts @@ -1396,7 +1396,7 @@ export interface FeatureFlag { __typename: 'FeatureFlag' } -export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_EMAIL_GROUP_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_REST_METADATA_API_NEW_FORMAT_DIRECT' | 'IS_LOGIC_FUNCTION_PREBUILT_MODE_ENABLED' | 'IS_SETTINGS_DISCOVERY_HERO_ENABLED' | 'IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED' +export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_EMAIL_GROUP_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_REST_METADATA_API_NEW_FORMAT_DIRECT' | 'IS_LOGIC_FUNCTION_PREBUILT_MODE_ENABLED' | 'IS_SETTINGS_DISCOVERY_HERO_ENABLED' | 'IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED' | 'IS_WORKFLOW_VERSION_IN_CORE_ENABLED' export interface WorkspaceUrls { customUrl?: Scalars['String'] @@ -9243,7 +9243,8 @@ export const enumFeatureFlagKey = { IS_REST_METADATA_API_NEW_FORMAT_DIRECT: 'IS_REST_METADATA_API_NEW_FORMAT_DIRECT' as const, IS_LOGIC_FUNCTION_PREBUILT_MODE_ENABLED: 'IS_LOGIC_FUNCTION_PREBUILT_MODE_ENABLED' as const, IS_SETTINGS_DISCOVERY_HERO_ENABLED: 'IS_SETTINGS_DISCOVERY_HERO_ENABLED' as const, - IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED: 'IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED' as const + IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED: 'IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED' as const, + IS_WORKFLOW_VERSION_IN_CORE_ENABLED: 'IS_WORKFLOW_VERSION_IN_CORE_ENABLED' as const } export const enumIdentityProviderType = { diff --git a/packages/twenty-front/src/generated-admin/graphql.ts b/packages/twenty-front/src/generated-admin/graphql.ts index 02cf3c6f47..456e645b73 100644 --- a/packages/twenty-front/src/generated-admin/graphql.ts +++ b/packages/twenty-front/src/generated-admin/graphql.ts @@ -320,7 +320,8 @@ export enum FeatureFlagKey { IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED = 'IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED', IS_REST_METADATA_API_NEW_FORMAT_DIRECT = 'IS_REST_METADATA_API_NEW_FORMAT_DIRECT', IS_SETTINGS_DISCOVERY_HERO_ENABLED = 'IS_SETTINGS_DISCOVERY_HERO_ENABLED', - IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED' + IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED', + IS_WORKFLOW_VERSION_IN_CORE_ENABLED = 'IS_WORKFLOW_VERSION_IN_CORE_ENABLED' } export type FindApplicationRegistrationInstalledWorkspacesInput = { diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 8b4740c8c6..7c486b397e 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -1759,7 +1759,8 @@ export enum FeatureFlagKey { IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED = 'IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED', IS_REST_METADATA_API_NEW_FORMAT_DIRECT = 'IS_REST_METADATA_API_NEW_FORMAT_DIRECT', IS_SETTINGS_DISCOVERY_HERO_ENABLED = 'IS_SETTINGS_DISCOVERY_HERO_ENABLED', - IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED' + IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED', + IS_WORKFLOW_VERSION_IN_CORE_ENABLED = 'IS_WORKFLOW_VERSION_IN_CORE_ENABLED' } export type Field = { diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-instance-command-fast-1783512000000-create-workflow-version-core-table.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-instance-command-fast-1783512000000-create-workflow-version-core-table.ts new file mode 100644 index 0000000000..e9412e808a --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-instance-command-fast-1783512000000-create-workflow-version-core-table.ts @@ -0,0 +1,45 @@ +import { QueryRunner } from 'typeorm'; + +import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator'; +import { FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface'; + +@RegisteredInstanceCommand('2.20.0', 1783512000000) +export class CreateWorkflowVersionCoreTableFastInstanceCommand + implements FastInstanceCommand +{ + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `DO $$ BEGIN CREATE TYPE "core"."workflowVersion_status_enum" AS ENUM ('DRAFT', 'ACTIVE', 'DEACTIVATED', 'ARCHIVED'); EXCEPTION WHEN duplicate_object THEN null; END $$`, + ); + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS "core"."workflowVersion" ( + "id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), + "triggers" jsonb, + "steps" jsonb, + "status" "core"."workflowVersion_status_enum" NOT NULL DEFAULT 'DRAFT', + "workflowId" uuid NOT NULL, + "workspaceId" uuid NOT NULL, + CONSTRAINT "PK_workflowVersion_id" PRIMARY KEY ("id"), + CONSTRAINT "FK_4316468725741b8e11e02b144f3" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE + )`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "IDX_WORKFLOW_VERSION_WORKSPACE_ID" + ON "core"."workflowVersion" ("workspaceId")`, + ); + await queryRunner.query( + `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_WORKFLOW_VERSION_ONE_ACTIVE_PER_WORKFLOW" + ON "core"."workflowVersion" ("workflowId") + WHERE "status" = 'ACTIVE'`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE IF EXISTS "core"."workflowVersion"`); + await queryRunner.query( + `DROP TYPE IF EXISTS "core"."workflowVersion_status_enum"`, + ); + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/create-workflow-version-core-table-upgrade-command-name.constant.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/create-workflow-version-core-table-upgrade-command-name.constant.ts new file mode 100644 index 0000000000..83d36cc0f3 --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/create-workflow-version-core-table-upgrade-command-name.constant.ts @@ -0,0 +1,4 @@ +// Referenced by @WasIntroducedInUpgrade on WorkflowVersionEntity so upgrade +// steps running below 2.20.0 don't query the table before this command creates it. +export const CREATE_WORKFLOW_VERSION_CORE_TABLE_UPGRADE_COMMAND_NAME = + '2.20.0_CreateWorkflowVersionCoreTableFastInstanceCommand_1783512000000'; diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts index cb8cb57485..ba89cc38ed 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts @@ -100,6 +100,7 @@ import { AddDisplayFieldsToApplicationRegistrationFastInstanceCommand } from './ import { BackfillDisplayFieldsOnApplicationRegistrationSlowInstanceCommand } from './2-19/2-19-instance-command-slow-1783073776591-backfill-display-fields-on-application-registration'; import { BackfillIsFeaturedOnApplicationRegistrationSlowInstanceCommand } from './2-19/2-19-instance-command-slow-1783120000000-backfill-is-featured-on-application-registration'; import { AllowServerScopedFileFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-20/2-20-instance-command-fast-1783499671541-allow-server-scoped-file'; +import { CreateWorkflowVersionCoreTableFastInstanceCommand } from './2-20/2-20-instance-command-fast-1783512000000-create-workflow-version-core-table'; export const INSTANCE_COMMANDS = [ AddViewFieldGroupIdIndexOnViewFieldFastInstanceCommand, @@ -202,4 +203,5 @@ export const INSTANCE_COMMANDS = [ AddPendingMimeCheckToFileFastInstanceCommand, BackfillIsFeaturedOnApplicationRegistrationSlowInstanceCommand, AllowServerScopedFileFastInstanceCommand, + CreateWorkflowVersionCoreTableFastInstanceCommand, ]; diff --git a/packages/twenty-server/src/engine/core-modules/workflow/entities/workflow-version.entity.ts b/packages/twenty-server/src/engine/core-modules/workflow/entities/workflow-version.entity.ts new file mode 100644 index 0000000000..6a856dbcdf --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/workflow/entities/workflow-version.entity.ts @@ -0,0 +1,58 @@ +import { + Column, + CreateDateColumn, + Entity, + Index, + PrimaryGeneratedColumn, + UpdateDateColumn, +} from 'typeorm'; + +import { CREATE_WORKFLOW_VERSION_CORE_TABLE_UPGRADE_COMMAND_NAME } from 'src/database/commands/upgrade-version-command/2-20/create-workflow-version-core-table-upgrade-command-name.constant'; +import { WasIntroducedInUpgrade } from 'src/engine/core-modules/upgrade/decorators/was-introduced-in-upgrade.decorator'; +import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity'; +import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type'; +import { type WorkflowTrigger } from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type'; + +export enum WorkflowVersionStatus { + DRAFT = 'DRAFT', + ACTIVE = 'ACTIVE', + DEACTIVATED = 'DEACTIVATED', + ARCHIVED = 'ARCHIVED', +} + +@Entity({ name: 'workflowVersion', schema: 'core' }) +@WasIntroducedInUpgrade({ + upgradeCommandName: CREATE_WORKFLOW_VERSION_CORE_TABLE_UPGRADE_COMMAND_NAME, +}) +@Index('IDX_WORKFLOW_VERSION_WORKSPACE_ID', ['workspaceId']) +@Index('IDX_WORKFLOW_VERSION_ONE_ACTIVE_PER_WORKFLOW', ['workflowId'], { + unique: true, + where: `"status" = 'ACTIVE'`, +}) +export class WorkflowVersionEntity extends WorkspaceRelatedEntity { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ type: 'jsonb', nullable: true }) + triggers: WorkflowTrigger[] | null; + + @Column({ type: 'jsonb', nullable: true }) + steps: WorkflowAction[] | null; + + @Column({ + type: 'enum', + enum: WorkflowVersionStatus, + default: WorkflowVersionStatus.DRAFT, + nullable: false, + }) + status: WorkflowVersionStatus; + + @Column({ type: 'uuid', nullable: false }) + workflowId: string; + + @CreateDateColumn({ type: 'timestamptz' }) + createdAt: Date; + + @UpdateDateColumn({ type: 'timestamptz' }) + updatedAt: Date; +} diff --git a/packages/twenty-server/src/engine/core-modules/workflow/services/workspace-workflow-automated-trigger-map-cache.service.ts b/packages/twenty-server/src/engine/core-modules/workflow/services/workspace-workflow-automated-trigger-map-cache.service.ts new file mode 100644 index 0000000000..9b4a342230 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/workflow/services/workspace-workflow-automated-trigger-map-cache.service.ts @@ -0,0 +1,47 @@ +import { Injectable } from '@nestjs/common'; + +import { isDefined } from 'twenty-shared/utils'; + +import { + WorkflowVersionEntity, + WorkflowVersionStatus, +} from 'src/engine/core-modules/workflow/entities/workflow-version.entity'; +import { type WorkflowAutomatedTriggerMaps } from 'src/engine/core-modules/workflow/types/workflow-automated-trigger-maps.type'; +import { computeAutomatedTriggerFromWorkflowVersion } from 'src/engine/core-modules/workflow/utils/compute-automated-trigger-from-workflow-version.util'; +import { InjectWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/inject-workspace-scoped-repository.decorator'; +import { WorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/workspace-scoped-repository'; +import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator'; +import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service'; + +@Injectable() +@WorkspaceCache('workflowAutomatedTriggerMaps') +export class WorkspaceWorkflowAutomatedTriggerMapCacheService extends WorkspaceCacheProvider { + constructor( + @InjectWorkspaceScopedRepository(WorkflowVersionEntity) + private readonly workflowVersionRepository: WorkspaceScopedRepository, + ) { + super(); + } + + async computeForCache( + workspaceId: string, + ): Promise { + const activeWorkflowVersions = await this.workflowVersionRepository.find( + workspaceId, + { where: { status: WorkflowVersionStatus.ACTIVE } }, + ); + + const byWorkflowId: WorkflowAutomatedTriggerMaps['byWorkflowId'] = {}; + + for (const workflowVersion of activeWorkflowVersions) { + const automatedTrigger = + computeAutomatedTriggerFromWorkflowVersion(workflowVersion); + + if (isDefined(automatedTrigger)) { + byWorkflowId[workflowVersion.workflowId] = automatedTrigger; + } + } + + return { byWorkflowId }; + } +} diff --git a/packages/twenty-server/src/engine/core-modules/workflow/types/workflow-automated-trigger-maps.type.ts b/packages/twenty-server/src/engine/core-modules/workflow/types/workflow-automated-trigger-maps.type.ts new file mode 100644 index 0000000000..5a35884766 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/workflow/types/workflow-automated-trigger-maps.type.ts @@ -0,0 +1,13 @@ +import { type AutomatedTriggerType } from 'src/modules/workflow/common/standard-objects/workflow-automated-trigger.workspace-entity'; +import { type AutomatedTriggerSettings } from 'src/modules/workflow/workflow-trigger/automated-trigger/constants/automated-trigger-settings'; + +export type CachedWorkflowAutomatedTrigger = { + workflowId: string; + workflowVersionId: string; + type: AutomatedTriggerType; + settings: AutomatedTriggerSettings; +}; + +export type WorkflowAutomatedTriggerMaps = { + byWorkflowId: Record; +}; diff --git a/packages/twenty-server/src/engine/core-modules/workflow/utils/compute-automated-trigger-from-workflow-version.util.ts b/packages/twenty-server/src/engine/core-modules/workflow/utils/compute-automated-trigger-from-workflow-version.util.ts new file mode 100644 index 0000000000..8d2b02f729 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/workflow/utils/compute-automated-trigger-from-workflow-version.util.ts @@ -0,0 +1,38 @@ +import { type WorkflowVersionEntity } from 'src/engine/core-modules/workflow/entities/workflow-version.entity'; +import { type CachedWorkflowAutomatedTrigger } from 'src/engine/core-modules/workflow/types/workflow-automated-trigger-maps.type'; +import { AutomatedTriggerType } from 'src/modules/workflow/common/standard-objects/workflow-automated-trigger.workspace-entity'; +import { type DatabaseEventTriggerSettings } from 'src/modules/workflow/workflow-trigger/automated-trigger/constants/automated-trigger-settings'; +import { WorkflowTriggerType } from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type'; +import { computeCronPatternFromSchedule } from 'src/modules/workflow/workflow-trigger/utils/compute-cron-pattern-from-schedule'; + +export const computeAutomatedTriggerFromWorkflowVersion = ( + workflowVersion: WorkflowVersionEntity, +): CachedWorkflowAutomatedTrigger | null => { + const trigger = workflowVersion.triggers?.[0] ?? null; + + if (trigger === null) { + return null; + } + + switch (trigger.type) { + case WorkflowTriggerType.DATABASE_EVENT: + return { + workflowId: workflowVersion.workflowId, + workflowVersionId: workflowVersion.id, + type: AutomatedTriggerType.DATABASE_EVENT, + settings: trigger.settings as DatabaseEventTriggerSettings, + }; + case WorkflowTriggerType.CRON: + return { + workflowId: workflowVersion.workflowId, + workflowVersionId: workflowVersion.id, + type: AutomatedTriggerType.CRON, + settings: { pattern: computeCronPatternFromSchedule(trigger) }, + }; + case WorkflowTriggerType.MANUAL: + case WorkflowTriggerType.WEBHOOK: + return null; + default: + return null; + } +}; diff --git a/packages/twenty-server/src/engine/core-modules/workflow/workflow-api.module.ts b/packages/twenty-server/src/engine/core-modules/workflow/workflow-api.module.ts index c16bf52d53..06fb39e977 100644 --- a/packages/twenty-server/src/engine/core-modules/workflow/workflow-api.module.ts +++ b/packages/twenty-server/src/engine/core-modules/workflow/workflow-api.module.ts @@ -8,6 +8,7 @@ import { WorkflowTriggerResolver } from 'src/engine/core-modules/workflow/resolv import { WorkflowVersionEdgeResolver } from 'src/engine/core-modules/workflow/resolvers/workflow-version-edge.resolver'; import { WorkflowVersionStepResolver } from 'src/engine/core-modules/workflow/resolvers/workflow-version-step.resolver'; import { WorkflowVersionResolver } from 'src/engine/core-modules/workflow/resolvers/workflow-version.resolver'; +import { WorkflowVersionCoreModule } from 'src/engine/core-modules/workflow/workflow-version-core.module'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { ConnectedAccountMetadataModule } from 'src/engine/metadata-modules/connected-account/connected-account-metadata.module'; import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module'; @@ -36,6 +37,7 @@ import { WorkflowTriggerModule } from 'src/modules/workflow/workflow-trigger/wor CodeStepBuildModule, WorkspaceManyOrAllFlatEntityMapsCacheModule, ConnectedAccountMetadataModule, + WorkflowVersionCoreModule, ], controllers: [WorkflowTriggerController], providers: [ diff --git a/packages/twenty-server/src/engine/core-modules/workflow/workflow-version-core.module.ts b/packages/twenty-server/src/engine/core-modules/workflow/workflow-version-core.module.ts new file mode 100644 index 0000000000..48132b5d0d --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/workflow/workflow-version-core.module.ts @@ -0,0 +1,16 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { WorkflowVersionEntity } from 'src/engine/core-modules/workflow/entities/workflow-version.entity'; +import { WorkspaceWorkflowAutomatedTriggerMapCacheService } from 'src/engine/core-modules/workflow/services/workspace-workflow-automated-trigger-map-cache.service'; +import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspace-scoped-repository/provide-workspace-scoped-repository'; + +@Module({ + imports: [TypeOrmModule.forFeature([WorkflowVersionEntity])], + providers: [ + WorkspaceWorkflowAutomatedTriggerMapCacheService, + provideWorkspaceScopedRepository(WorkflowVersionEntity), + ], + exports: [TypeOrmModule, WorkspaceWorkflowAutomatedTriggerMapCacheService], +}) +export class WorkflowVersionCoreModule {} diff --git a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts index a9301fd032..b74c437f3a 100644 --- a/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts +++ b/packages/twenty-server/src/engine/twenty-orm/entity-manager/workspace-entity-manager.spec.ts @@ -242,6 +242,7 @@ describe('WorkspaceEntityManager', () => { IS_LOGIC_FUNCTION_PREBUILT_MODE_ENABLED: false, IS_SETTINGS_DISCOVERY_HERO_ENABLED: false, IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED: false, + IS_WORKFLOW_VERSION_IN_CORE_ENABLED: false, }, userWorkspaceRoleMap: {}, apiKeyRoleMap: {}, diff --git a/packages/twenty-server/src/engine/workspace-cache/types/workspace-cache-key.type.ts b/packages/twenty-server/src/engine/workspace-cache/types/workspace-cache-key.type.ts index 6977699b78..c2ce745097 100644 --- a/packages/twenty-server/src/engine/workspace-cache/types/workspace-cache-key.type.ts +++ b/packages/twenty-server/src/engine/workspace-cache/types/workspace-cache-key.type.ts @@ -10,6 +10,7 @@ import { type ApplicationVariableCacheMaps } from 'src/engine/core-modules/appli import { type FlatApplicationCacheMaps } from 'src/engine/core-modules/application/types/flat-application-cache-maps.type'; import { type CurrentBillingSubscription } from 'src/engine/core-modules/billing/types/flat-billing-subscription.type'; import { type FlatWorkspaceMemberMaps } from 'src/engine/core-modules/user/types/flat-workspace-member-maps.type'; +import { type WorkflowAutomatedTriggerMaps } from 'src/engine/core-modules/workflow/types/workflow-automated-trigger-maps.type'; import { type FlatRoleTargetByAgentIdMaps } from 'src/engine/metadata-modules/flat-agent/types/flat-role-target-by-agent-id-maps.type'; import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type'; import { type UserWorkspaceRoleMap } from 'src/engine/metadata-modules/role-target/types/user-workspace-role-map'; @@ -62,6 +63,7 @@ export const WORKSPACE_CACHE_KEYS_V2 = { applicationVariableMaps: 'cache:application-variable', graphQLResolverNameMap: 'direct-execution:graphql-resolver-name-map', currentBillingSubscription: 'billing:subscription', + workflowAutomatedTriggerMaps: 'cache:workflow-automated-trigger', } as const satisfies Record; export type AdditionalCacheDataMaps = { @@ -79,6 +81,7 @@ export type AdditionalCacheDataMaps = { applicationVariableMaps: ApplicationVariableCacheMaps; graphQLResolverNameMap: Record; currentBillingSubscription: CurrentBillingSubscription; + workflowAutomatedTriggerMaps: WorkflowAutomatedTriggerMaps; }; export type WorkspaceCacheDataMap = AllFlatEntityMaps & diff --git a/packages/twenty-shared/src/types/FeatureFlagKey.ts b/packages/twenty-shared/src/types/FeatureFlagKey.ts index 463eda1bac..e87a2a3272 100644 --- a/packages/twenty-shared/src/types/FeatureFlagKey.ts +++ b/packages/twenty-shared/src/types/FeatureFlagKey.ts @@ -7,4 +7,5 @@ export enum FeatureFlagKey { IS_LOGIC_FUNCTION_PREBUILT_MODE_ENABLED = 'IS_LOGIC_FUNCTION_PREBUILT_MODE_ENABLED', IS_SETTINGS_DISCOVERY_HERO_ENABLED = 'IS_SETTINGS_DISCOVERY_HERO_ENABLED', IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED = 'IS_MESSAGING_CALENDAR_WEBHOOK_ENABLED', + IS_WORKFLOW_VERSION_IN_CORE_ENABLED = 'IS_WORKFLOW_VERSION_IN_CORE_ENABLED', }