diff --git a/packages/twenty-server/src/database/commands/cron-register-all.command.ts b/packages/twenty-server/src/database/commands/cron-register-all.command.ts index ba3d608683..70264dc1af 100644 --- a/packages/twenty-server/src/database/commands/cron-register-all.command.ts +++ b/packages/twenty-server/src/database/commands/cron-register-all.command.ts @@ -14,6 +14,7 @@ import { WorkflowCleanWorkflowRunsCommand } from 'src/modules/workflow/workflow- import { WorkflowHandleStaledRunsCronCommand } from 'src/modules/workflow/workflow-runner/workflow-run-queue/cron/command/workflow-handle-staled-runs.cron.command'; import { WorkflowRunEnqueueCronCommand } from 'src/modules/workflow/workflow-runner/workflow-run-queue/cron/command/workflow-run-enqueue.cron.command'; import { WorkflowCronTriggerCronCommand } from 'src/modules/workflow/workflow-trigger/automated-trigger/crons/commands/workflow-cron-trigger.cron.command'; +import { CronTriggerCronCommand } from 'src/engine/metadata-modules/trigger/crons/commands/cron-trigger.cron.command'; @Command({ name: 'cron:register:all', @@ -35,6 +36,7 @@ export class CronRegisterAllCommand extends CommandRunner { private readonly workflowRunEnqueueCronCommand: WorkflowRunEnqueueCronCommand, private readonly workflowHandleStaledRunsCronCommand: WorkflowHandleStaledRunsCronCommand, private readonly workflowCleanWorkflowRunsCronCommand: WorkflowCleanWorkflowRunsCommand, + private readonly cronTriggerCronCommand: CronTriggerCronCommand, ) { super(); } @@ -91,6 +93,10 @@ export class CronRegisterAllCommand extends CommandRunner { name: 'WorkflowCleanWorkflowRuns', command: this.workflowCleanWorkflowRunsCronCommand, }, + { + name: 'CronTrigger', + command: this.cronTriggerCronCommand, + }, ]; let successCount = 0; diff --git a/packages/twenty-server/src/database/commands/database-command.module.ts b/packages/twenty-server/src/database/commands/database-command.module.ts index 330008f20d..a4b45502f6 100644 --- a/packages/twenty-server/src/database/commands/database-command.module.ts +++ b/packages/twenty-server/src/database/commands/database-command.module.ts @@ -21,6 +21,7 @@ import { CalendarEventImportManagerModule } from 'src/modules/calendar/calendar- import { MessagingImportManagerModule } from 'src/modules/messaging/message-import-manager/messaging-import-manager.module'; import { WorkflowRunQueueModule } from 'src/modules/workflow/workflow-runner/workflow-run-queue/workflow-run-queue.module'; import { AutomatedTriggerModule } from 'src/modules/workflow/workflow-trigger/automated-trigger/automated-trigger.module'; +import { TriggerModule } from 'src/engine/metadata-modules/trigger/trigger.module'; import { DataSeedWorkspaceCommand } from './data-seed-dev-workspace.command'; @@ -45,6 +46,7 @@ import { DataSeedWorkspaceCommand } from './data-seed-dev-workspace.command'; WorkspaceCacheStorageModule, ApiKeyModule, FeatureFlagModule, + TriggerModule, ], providers: [ DataSeedWorkspaceCommand, diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/common/1756373902817-addCronTriggerEntity.ts b/packages/twenty-server/src/database/typeorm/core/migrations/common/1756373902817-addCronTriggerEntity.ts new file mode 100644 index 0000000000..8e74d658e2 --- /dev/null +++ b/packages/twenty-server/src/database/typeorm/core/migrations/common/1756373902817-addCronTriggerEntity.ts @@ -0,0 +1,27 @@ +import { type MigrationInterface, type QueryRunner } from 'typeorm'; + +export class AddCronTriggerEntity1756373902817 implements MigrationInterface { + name = 'AddCronTriggerEntity1756373902817'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "core"."cronTrigger" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "settings" jsonb NOT NULL, "workspaceId" uuid NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "serverlessFunctionId" uuid, CONSTRAINT "PK_153e054abdb2663942d4661e3bb" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE INDEX "IDX_CRON_TRIGGER_WORKSPACE_ID" ON "core"."cronTrigger" ("workspaceId") `, + ); + await queryRunner.query( + `ALTER TABLE "core"."cronTrigger" ADD CONSTRAINT "FK_f70831ec336e0cb42d6a33b80ba" FOREIGN KEY ("serverlessFunctionId") REFERENCES "core"."serverlessFunction"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."cronTrigger" DROP CONSTRAINT "FK_f70831ec336e0cb42d6a33b80ba"`, + ); + await queryRunner.query( + `DROP INDEX "core"."IDX_CRON_TRIGGER_WORKSPACE_ID"`, + ); + await queryRunner.query(`DROP TABLE "core"."cronTrigger"`); + } +} diff --git a/packages/twenty-server/src/engine/core-modules/message-queue/jobs.module.ts b/packages/twenty-server/src/engine/core-modules/message-queue/jobs.module.ts index 3572da1866..8c4783ddad 100644 --- a/packages/twenty-server/src/engine/core-modules/message-queue/jobs.module.ts +++ b/packages/twenty-server/src/engine/core-modules/message-queue/jobs.module.ts @@ -33,6 +33,8 @@ import { TimelineJobModule } from 'src/modules/timeline/jobs/timeline-job.module import { TimelineActivityModule } from 'src/modules/timeline/timeline-activity.module'; import { WebhookJobModule } from 'src/engine/core-modules/webhook/jobs/webhook-job.module'; import { WorkflowModule } from 'src/modules/workflow/workflow.module'; +import { TriggerModule } from 'src/engine/metadata-modules/trigger/trigger.module'; +import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module'; @Module({ imports: [ @@ -60,6 +62,8 @@ import { WorkflowModule } from 'src/modules/workflow/workflow.module'; WorkspaceCleanerModule, SubscriptionsModule, AuditJobModule, + TriggerModule, + ServerlessFunctionModule, ], providers: [ CleanSuspendedWorkspacesJob, diff --git a/packages/twenty-server/src/engine/core-modules/message-queue/message-queue.constants.ts b/packages/twenty-server/src/engine/core-modules/message-queue/message-queue.constants.ts index a1277d8e74..7e34c5b593 100644 --- a/packages/twenty-server/src/engine/core-modules/message-queue/message-queue.constants.ts +++ b/packages/twenty-server/src/engine/core-modules/message-queue/message-queue.constants.ts @@ -16,4 +16,5 @@ export enum MessageQueue { workflowQueue = 'workflow-queue', deleteCascadeQueue = 'delete-cascade-queue', subscriptionsQueue = 'subscriptions-queue', + serverlessFunctionQueue = 'serverless-function-queue', } diff --git a/packages/twenty-server/src/engine/metadata-modules/serverless-function/jobs/serverless-function-trigger.job.ts b/packages/twenty-server/src/engine/metadata-modules/serverless-function/jobs/serverless-function-trigger.job.ts new file mode 100644 index 0000000000..f92a788a54 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/serverless-function/jobs/serverless-function-trigger.job.ts @@ -0,0 +1,32 @@ +import { Scope } from '@nestjs/common'; + +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 { Process } from 'src/engine/core-modules/message-queue/decorators/process.decorator'; +import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service'; + +export type ServerlessFunctionTriggerJobData = { + serverlessFunctionId: string; + workspaceId: string; + payload?: object; +}; + +@Processor({ + queueName: MessageQueue.serverlessFunctionQueue, + scope: Scope.REQUEST, +}) +export class ServerlessFunctionTriggerJob { + constructor( + private readonly serverlessFunctionService: ServerlessFunctionService, + ) {} + + @Process(ServerlessFunctionTriggerJob.name) + async handle(data: ServerlessFunctionTriggerJobData) { + await this.serverlessFunctionService.executeOneServerlessFunction( + data.serverlessFunctionId, + data.workspaceId, + data.payload || {}, + 'draft', + ); + } +} 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 3826afd746..1c09e77c92 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 @@ -7,9 +7,11 @@ import { Index, PrimaryGeneratedColumn, UpdateDateColumn, + OneToMany, } from 'typeorm'; import { InputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/input-schema.type'; +import { CronTrigger } from 'src/engine/metadata-modules/trigger/entities/cron-trigger.entity'; const DEFAULT_SERVERLESS_TIMEOUT_SECONDS = 300; // 5 minutes @@ -52,6 +54,15 @@ export class ServerlessFunctionEntity { @Column({ nullable: false, type: 'uuid' }) workspaceId: string; + @OneToMany( + () => CronTrigger, + (cronTrigger) => cronTrigger.serverlessFunction, + { + cascade: true, + }, + ) + cronTriggers: CronTrigger[]; + @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 2f08044c88..11b25e1a68 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,6 +12,7 @@ import { ThrottlerModule } from 'src/engine/core-modules/throttler/throttler.mod import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; import { ServerlessFunctionResolver } from 'src/engine/metadata-modules/serverless-function/serverless-function.resolver'; import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service'; +import { ServerlessFunctionTriggerJob } from 'src/engine/metadata-modules/serverless-function/jobs/serverless-function-trigger.job'; @Module({ imports: [ @@ -23,7 +24,11 @@ import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverles AuditModule, FeatureFlagModule, ], - providers: [ServerlessFunctionService, ServerlessFunctionResolver], + providers: [ + ServerlessFunctionService, + ServerlessFunctionTriggerJob, + ServerlessFunctionResolver, + ], exports: [ServerlessFunctionService], }) export class ServerlessFunctionModule {} diff --git a/packages/twenty-server/src/engine/metadata-modules/trigger/crons/commands/cron-trigger.cron.command.ts b/packages/twenty-server/src/engine/metadata-modules/trigger/crons/commands/cron-trigger.cron.command.ts new file mode 100644 index 0000000000..85c2ff59d0 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/trigger/crons/commands/cron-trigger.cron.command.ts @@ -0,0 +1,34 @@ +import { Command, CommandRunner } from 'nest-commander'; + +import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.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 { + CRON_TRIGGER_CRON_PATTERN, + CronTriggerCronJob, +} from 'src/engine/metadata-modules/trigger/crons/jobs/cron-trigger.cron.job'; +@Command({ + name: 'cron:trigger:start-cron-trigger', + description: + 'Starts a cron job to trigger cron triggered serverless functions', +}) +export class CronTriggerCronCommand extends CommandRunner { + constructor( + @InjectMessageQueue(MessageQueue.cronQueue) + private readonly messageQueueService: MessageQueueService, + ) { + super(); + } + + async run(): Promise { + await this.messageQueueService.addCron({ + jobName: CronTriggerCronJob.name, + data: undefined, + options: { + repeat: { + pattern: CRON_TRIGGER_CRON_PATTERN, + }, + }, + }); + } +} diff --git a/packages/twenty-server/src/engine/metadata-modules/trigger/crons/jobs/cron-trigger.cron.job.ts b/packages/twenty-server/src/engine/metadata-modules/trigger/crons/jobs/cron-trigger.cron.job.ts new file mode 100644 index 0000000000..1b5ba51526 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/trigger/crons/jobs/cron-trigger.cron.job.ts @@ -0,0 +1,78 @@ +import { InjectRepository } from '@nestjs/typeorm'; + +import { isDefined } from 'twenty-shared/utils'; +import { WorkspaceActivationStatus } from 'twenty-shared/workspace'; +import { 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'; +import { Process } from 'src/engine/core-modules/message-queue/decorators/process.decorator'; +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 { CronTrigger } from 'src/engine/metadata-modules/trigger/entities/cron-trigger.entity'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { + ServerlessFunctionTriggerJob, + ServerlessFunctionTriggerJobData, +} from 'src/engine/metadata-modules/serverless-function/jobs/serverless-function-trigger.job'; +import { shouldRunNow } from 'src/utils/should-run-now.utils'; + +export const CRON_TRIGGER_CRON_PATTERN = '* * * * *'; + +@Processor(MessageQueue.cronQueue) +export class CronTriggerCronJob { + constructor( + @InjectMessageQueue(MessageQueue.serverlessFunctionQueue) + private readonly messageQueueService: MessageQueueService, + @InjectRepository(Workspace) + private readonly workspaceRepository: Repository, + @InjectRepository(CronTrigger) + private readonly cronTriggerRepository: Repository, + ) {} + + @Process(CronTriggerCronJob.name) + @SentryCronMonitor(CronTriggerCronJob.name, CRON_TRIGGER_CRON_PATTERN) + async handle() { + const activeWorkspaces = await this.workspaceRepository.find({ + where: { + activationStatus: WorkspaceActivationStatus.ACTIVE, + }, + select: ['id'], + }); + + const now = new Date(); + + for (const activeWorkspace of activeWorkspaces) { + const cronTriggers = await this.cronTriggerRepository.find({ + where: { + workspaceId: activeWorkspace.id, + }, + select: ['settings'], + relations: ['serverlessFunction'], + }); + + for (const cronTrigger of cronTriggers) { + const settings = cronTrigger.settings; + + if (!isDefined(settings.pattern)) { + continue; + } + + if (!shouldRunNow(settings.pattern, now)) { + continue; + } + + await this.messageQueueService.add( + ServerlessFunctionTriggerJob.name, + { + serverlessFunctionId: cronTrigger.serverlessFunction.id, + workspaceId: activeWorkspace.id, + payload: {}, + }, + { retryLimit: 3 }, + ); + } + } + } +} diff --git a/packages/twenty-server/src/engine/metadata-modules/trigger/entities/cron-trigger.entity.ts b/packages/twenty-server/src/engine/metadata-modules/trigger/entities/cron-trigger.entity.ts new file mode 100644 index 0000000000..7bb244408b --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/trigger/entities/cron-trigger.entity.ts @@ -0,0 +1,48 @@ +import { + Column, + CreateDateColumn, + Entity, + DeleteDateColumn, + JoinColumn, + ManyToOne, + PrimaryGeneratedColumn, + UpdateDateColumn, + Relation, + Index, +} from 'typeorm'; + +import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity'; + +export type CronTriggerSettings = { + pattern: string; +}; + +@Entity({ name: 'cronTrigger', schema: 'core' }) +@Index('IDX_CRON_TRIGGER_WORKSPACE_ID', ['workspaceId']) +export class CronTrigger { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ nullable: false, type: 'jsonb' }) + settings: CronTriggerSettings; + + @ManyToOne( + () => ServerlessFunctionEntity, + (serverlessFunction) => serverlessFunction.cronTriggers, + { onDelete: 'CASCADE' }, + ) + @JoinColumn({ name: 'serverlessFunctionId' }) + serverlessFunction: Relation; + + @Column({ nullable: false, type: 'uuid' }) + workspaceId: string; + + @CreateDateColumn({ type: 'timestamptz' }) + createdAt: Date; + + @UpdateDateColumn({ type: 'timestamptz' }) + updatedAt: Date; + + @DeleteDateColumn({ type: 'timestamptz' }) + deletedAt?: Date; +} diff --git a/packages/twenty-server/src/engine/metadata-modules/trigger/trigger.module.ts b/packages/twenty-server/src/engine/metadata-modules/trigger/trigger.module.ts new file mode 100644 index 0000000000..4b56c651e1 --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/trigger/trigger.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { CronTriggerCronCommand } from 'src/engine/metadata-modules/trigger/crons/commands/cron-trigger.cron.command'; +import { CronTriggerCronJob } from 'src/engine/metadata-modules/trigger/crons/jobs/cron-trigger.cron.job'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { CronTrigger } from 'src/engine/metadata-modules/trigger/entities/cron-trigger.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([Workspace, CronTrigger])], + providers: [CronTriggerCronJob, CronTriggerCronCommand], + exports: [CronTriggerCronCommand], +}) +export class TriggerModule {} diff --git a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/automated-trigger.module.ts b/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/automated-trigger.module.ts index ae895089d2..c889a9dcf1 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/automated-trigger.module.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/automated-trigger.module.ts @@ -6,7 +6,7 @@ import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/works import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module'; import { AutomatedTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/automated-trigger/automated-trigger.workspace-service'; import { WorkflowCronTriggerCronCommand } from 'src/modules/workflow/workflow-trigger/automated-trigger/crons/commands/workflow-cron-trigger.cron.command'; -import { CronTriggerCronJob } from 'src/modules/workflow/workflow-trigger/automated-trigger/crons/jobs/cron-trigger.cron.job'; +import { WorkflowCronTriggerCronJob } from 'src/modules/workflow/workflow-trigger/automated-trigger/crons/jobs/workflow-cron-trigger-cron.job'; import { DatabaseEventTriggerListener } from 'src/modules/workflow/workflow-trigger/automated-trigger/listeners/database-event-trigger.listener'; @Module({ @@ -18,7 +18,7 @@ import { DatabaseEventTriggerListener } from 'src/modules/workflow/workflow-trig providers: [ AutomatedTriggerWorkspaceService, DatabaseEventTriggerListener, - CronTriggerCronJob, + WorkflowCronTriggerCronJob, WorkflowCronTriggerCronCommand, ], exports: [AutomatedTriggerWorkspaceService, WorkflowCronTriggerCronCommand], diff --git a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/commands/workflow-cron-trigger.cron.command.ts b/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/commands/workflow-cron-trigger.cron.command.ts index de07c9361b..64dbfe8a70 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/commands/workflow-cron-trigger.cron.command.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/commands/workflow-cron-trigger.cron.command.ts @@ -4,9 +4,9 @@ import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decora 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 { - CRON_TRIGGER_CRON_PATTERN, - CronTriggerCronJob, -} from 'src/modules/workflow/workflow-trigger/automated-trigger/crons/jobs/cron-trigger.cron.job'; + WORKFLOW_CRON_TRIGGER_CRON_PATTERN, + WorkflowCronTriggerCronJob, +} from 'src/modules/workflow/workflow-trigger/automated-trigger/crons/jobs/workflow-cron-trigger-cron.job'; @Command({ name: 'cron:workflow:automated-cron-trigger', @@ -22,11 +22,11 @@ export class WorkflowCronTriggerCronCommand extends CommandRunner { async run(): Promise { await this.messageQueueService.addCron({ - jobName: CronTriggerCronJob.name, + jobName: WorkflowCronTriggerCronJob.name, data: undefined, options: { repeat: { - pattern: CRON_TRIGGER_CRON_PATTERN, + pattern: WORKFLOW_CRON_TRIGGER_CRON_PATTERN, }, }, }); diff --git a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/jobs/cron-trigger.cron.job.ts b/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/jobs/workflow-cron-trigger-cron.job.ts similarity index 91% rename from packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/jobs/cron-trigger.cron.job.ts rename to packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/jobs/workflow-cron-trigger-cron.job.ts index 427f4f05ee..3f102d3ef0 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/jobs/cron-trigger.cron.job.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/jobs/workflow-cron-trigger-cron.job.ts @@ -15,16 +15,16 @@ import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { getWorkspaceSchemaName } from 'src/engine/workspace-datasource/utils/get-workspace-schema-name.util'; import { AutomatedTriggerType } from 'src/modules/workflow/common/standard-objects/workflow-automated-trigger.workspace-entity'; import { type CronTriggerSettings } from 'src/modules/workflow/workflow-trigger/automated-trigger/constants/automated-trigger-settings'; -import { shouldRunNow } from 'src/modules/workflow/workflow-trigger/automated-trigger/crons/utils/should-run-now.utils'; import { WorkflowTriggerJob, type WorkflowTriggerJobData, } from 'src/modules/workflow/workflow-trigger/jobs/workflow-trigger.job'; +import { shouldRunNow } from 'src/utils/should-run-now.utils'; -export const CRON_TRIGGER_CRON_PATTERN = '* * * * *'; +export const WORKFLOW_CRON_TRIGGER_CRON_PATTERN = '* * * * *'; @Processor(MessageQueue.cronQueue) -export class CronTriggerCronJob { +export class WorkflowCronTriggerCronJob { constructor( @InjectDataSource() private readonly coreDataSource: DataSource, @@ -35,8 +35,11 @@ export class CronTriggerCronJob { private readonly exceptionHandlerService: ExceptionHandlerService, ) {} - @Process(CronTriggerCronJob.name) - @SentryCronMonitor(CronTriggerCronJob.name, CRON_TRIGGER_CRON_PATTERN) + @Process(WorkflowCronTriggerCronJob.name) + @SentryCronMonitor( + WorkflowCronTriggerCronJob.name, + WORKFLOW_CRON_TRIGGER_CRON_PATTERN, + ) async handle() { const activeWorkspaces = await this.workspaceRepository.find({ where: { diff --git a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/utils/tests/should-run-now.utils.spec.ts b/packages/twenty-server/src/utils/__test__/should-run-now.utils.spec.ts similarity index 92% rename from packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/utils/tests/should-run-now.utils.spec.ts rename to packages/twenty-server/src/utils/__test__/should-run-now.utils.spec.ts index a22296d071..c1fecc191f 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/utils/tests/should-run-now.utils.spec.ts +++ b/packages/twenty-server/src/utils/__test__/should-run-now.utils.spec.ts @@ -1,4 +1,4 @@ -import { shouldRunNow } from 'src/modules/workflow/workflow-trigger/automated-trigger/crons/utils/should-run-now.utils'; +import { shouldRunNow } from 'src/utils/should-run-now.utils'; const getNowDate = (hour: string) => { return new Date(`2025-01-01T${hour}.100Z`); diff --git a/packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/utils/should-run-now.utils.ts b/packages/twenty-server/src/utils/should-run-now.utils.ts similarity index 100% rename from packages/twenty-server/src/modules/workflow/workflow-trigger/automated-trigger/crons/utils/should-run-now.utils.ts rename to packages/twenty-server/src/utils/should-run-now.utils.ts