MCPcopy Index your code
hub / github.com/simstudioai/sim / classifyEligibility

Function classifyEligibility

apps/sim/lib/table/workflow-columns.ts:72–121  ·  view source on GitHub ↗
(
  group: WorkflowGroup,
  row: TableRow,
  opts?: { isManualRun?: boolean; mode?: DispatchMode }
)

Source from the content-addressed store, hash-verified

70 | 'deps-unmet'
71
72export function classifyEligibility(
73 group: WorkflowGroup,
74 row: TableRow,
75 opts?: { isManualRun?: boolean; mode?: DispatchMode }
76): EligibilityReason {
77 const isManualRun = opts?.isManualRun ?? false
78 const mode = opts?.mode ?? 'all'
79
80 if (group.autoRun === false && !isManualRun) return 'autoRun-off'
81
82 const exec = row.executions?.[group.id]
83 // Dispatcher pre-stamp orphans (`pending` + `executionId: null`) are
84 // placeholders left behind when a previous dispatcher loop wrote the stamp
85 // but no cell-task picked up (cascade-lock contention, trigger.dev queue
86 // failure, etc.). Treat them as claimable so a new dispatcher can re-enqueue
87 // — without this carve-out the row would render "Queued" forever. Matches
88 // the `pickNextEligibleGroupForRow` cascade-loop carve-out.
89 const isOrphanPreStamp = exec?.status === 'pending' && exec.executionId == null
90 if (!isOrphanPreStamp && isExecInFlight(exec)) return 'in-flight'
91 const status = exec?.status
92
93 // `mode: 'new'` is the auto-fire scope: only rows that have never been
94 // attempted on this group run. Any pre-existing exec entry — completed,
95 // cancelled, or error — keeps the cell sticky until the user manually
96 // re-runs via "Run column" / "Run all rows" / "Run this row".
97 // Exception: orphan pre-stamps are claimable (handled above).
98 if (mode === 'new' && exec && !isOrphanPreStamp) return 'has-prior-attempt'
99
100 const completedAndFilled = status === 'completed' && areOutputsFilled(group, row)
101 // For an enrichment a `completed` run is terminal even with empty outputs —
102 // a no-match is a real result, not an unfinished run. Treating it as "done"
103 // stops the auto cascade from re-invoking billable provider calls on every
104 // no-match row each dispatch. A genuine input change clears the exec entry
105 // (see deriveExecClearsForDataPatch), so real re-runs still happen.
106 const isDone = completedAndFilled || (group.type === 'enrichment' && status === 'completed')
107 if (!isManualRun && isDone) return 'completed-on-auto'
108 if (!isManualRun && status === 'error') return 'error-on-auto'
109 if (!isManualRun && status === 'cancelled') return 'cancelled-on-auto'
110 // Manual incomplete-mode runs (Run row / Run incomplete) treat a `completed`
111 // group as done even if an output is blank — only "Run all" re-runs it. The
112 // auto cascade still re-fills blank workflow outputs (completedAndFilled).
113 if (mode === 'incomplete') {
114 if (isManualRun ? status === 'completed' : isDone) {
115 return 'completed-on-incomplete'
116 }
117 }
118
119 if (isManualRun && group.autoRun === false) return 'manual-bypass'
120 return areGroupDepsSatisfied(group, row) ? 'eligible' : 'deps-unmet'
121}
122
123export function isGroupEligible(
124 group: WorkflowGroup,

Callers 2

isGroupEligibleFunction · 0.85
buildPendingRunsFunction · 0.85

Calls 3

isExecInFlightFunction · 0.90
areOutputsFilledFunction · 0.90
areGroupDepsSatisfiedFunction · 0.90

Tested by

no test coverage detected