From 62050c9c05abd383db7b3cb032c518fe647f62ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Thu, 16 Apr 2026 22:50:38 -0400 Subject: [PATCH] refactor(automation): use JSON-stringified execution keys P1-19: Previous string-join with ':' separator could collide when field values contain colons (e.g. runId='a:b' vs runId='a' + previousStatus='b'). Use JSON.stringify for unambiguous serialization. --- src/main/automation/index.ts | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/automation/index.ts b/src/main/automation/index.ts index 004c271d..b7e11e77 100644 --- a/src/main/automation/index.ts +++ b/src/main/automation/index.ts @@ -111,16 +111,16 @@ export function createAutomationService({ const rules = db.listActiveAutomationRules(ctx.companyId, trigger); for (const rule of rules) { if (!matchesConditions(db, rule, ctx)) continue; - const executionKey = [ - rule.id, + const executionKey = JSON.stringify({ + ruleId: rule.id, trigger, - ctx.companyId, - ctx.taskId ?? "-", - ctx.agentId ?? "-", - ctx.runId ?? "-", - ctx.previousStatus ?? "-", - ctx.newStatus ?? "-", - ].join(":"); + companyId: ctx.companyId, + taskId: ctx.taskId ?? null, + agentId: ctx.agentId ?? null, + runId: ctx.runId ?? null, + previousStatus: ctx.previousStatus ?? null, + newStatus: ctx.newStatus ?? null, + }); if (activeAutomationExecutions.has(executionKey)) { logger.warn(`[automation] Skipping re-entrant execution for rule "${rule.name}" (${executionKey})`); continue; @@ -168,16 +168,16 @@ export function createAutomationService({ const workflows = db.listTriggerableWorkflows(ctx.companyId, trigger); for (const workflow of workflows) { if (!matchesEventConfig(db, workflow.triggerConfigJson, null, ctx)) continue; - const executionKey = [ - workflow.id, + const executionKey = JSON.stringify({ + workflowId: workflow.id, trigger, - ctx.companyId, - ctx.taskId ?? "-", - ctx.agentId ?? "-", - ctx.runId ?? "-", - ctx.previousStatus ?? "-", - ctx.newStatus ?? "-", - ].join(":"); + companyId: ctx.companyId, + taskId: ctx.taskId ?? null, + agentId: ctx.agentId ?? null, + runId: ctx.runId ?? null, + previousStatus: ctx.previousStatus ?? null, + newStatus: ctx.newStatus ?? null, + }); if (activeWorkflowTriggerExecutions.has(executionKey)) { logger.warn(`[workflow] Skipping re-entrant trigger for workflow "${workflow.name}" (${executionKey})`); continue;