Skip to content

Commit 6b4d97f

Browse files
fix(enrichment): preserve unrelated table outputs
1 parent 5af324a commit 6b4d97f

5 files changed

Lines changed: 73 additions & 2 deletions

File tree

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/cell-render.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,16 @@ describe('resolveCellRender waiting precedence', () => {
6464
})
6565
).toEqual({ kind: 'value', text: 'person@old.example' })
6666
})
67+
68+
it('keeps ordinary workflow output visible when dependencies become unmet', () => {
69+
expect(
70+
resolveCellRender({
71+
value: 'kept workflow result',
72+
exec: execution('completed'),
73+
column: COLUMN,
74+
waitingOnLabels: ['Dependency'],
75+
isEnrichmentOutput: false,
76+
})
77+
).toEqual({ kind: 'value', text: 'kept workflow result' })
78+
})
6779
})

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/cells/cell-render.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export function resolveCellRender({
8484
* Waiting state must win over that stale value. Active reruns still keep
8585
* showing the previous value until their replacement lands.
8686
*/
87-
if (!inFlight && waitingOnLabels && waitingOnLabels.length > 0) {
87+
if (isEnrichmentOutput && !inFlight && waitingOnLabels && waitingOnLabels.length > 0) {
8888
return { kind: 'waiting', labels: waitingOnLabels }
8989
}
9090

apps/sim/lib/table/deps.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { describe, expect, it } from 'vitest'
55
import {
66
areGroupDepsSatisfied,
77
areOutputsFilled,
8+
getGroupInvalidationColumns,
89
getUnmetGroupDeps,
910
isEmptyCellValue,
1011
isExecCancelled,
@@ -139,6 +140,28 @@ describe('optimisticallyScheduleNewlyEligibleGroups — enrichment inputs', () =
139140

140141
expect(next).toEqual({})
141142
})
143+
144+
it('ignores legacy input mappings that point at the enrichment output', () => {
145+
const legacyGroup = {
146+
...group,
147+
inputMappings: [
148+
...(group.inputMappings ?? []),
149+
{ inputName: 'legacyEmail', columnName: 'g1_out' },
150+
],
151+
}
152+
153+
expect(getGroupInvalidationColumns(legacyGroup)).toEqual(['name', 'domain'])
154+
155+
const before = makeRow(
156+
{ name: 'Person Name', domain: 'old.example', g1_out: 'person@old.example' },
157+
{ g1: completedExec('wf-g1') }
158+
)
159+
const next = optimisticallyScheduleNewlyEligibleGroups([legacyGroup], columns, before, {
160+
g1_out: 'user-edited@example.com',
161+
})
162+
163+
expect(next).toBeNull()
164+
})
142165
})
143166

144167
function completedExec(workflowId: string): RowExecutionMetadata {

apps/sim/lib/table/deps.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,10 @@ export function getUnmetGroupDeps(group: WorkflowGroup, row: TableRow): UnmetDep
129129
export function getGroupInvalidationColumns(group: WorkflowGroup): string[] {
130130
const columns = new Set(group.dependencies?.columns ?? [])
131131
if (group.type === 'enrichment') {
132-
for (const mapping of group.inputMappings ?? []) columns.add(mapping.columnName)
132+
const ownOutputColumns = new Set(group.outputs.map((output) => output.columnName))
133+
for (const mapping of group.inputMappings ?? []) {
134+
if (!ownOutputColumns.has(mapping.columnName)) columns.add(mapping.columnName)
135+
}
133136
}
134137
return [...columns]
135138
}

apps/sim/lib/table/rows/executions.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,37 @@ describe('deriveExecClearsForDataPatch enrichment inputs', () => {
205205

206206
expect(result.executionsPatch).toEqual({ [MANUAL_ENRICHMENT_GROUP.id]: null })
207207
})
208+
209+
it('does not re-arm when a legacy input mapping points at the enrichment output', () => {
210+
const legacyGroup: WorkflowGroup = {
211+
...MANUAL_ENRICHMENT_GROUP,
212+
inputMappings: [
213+
...(MANUAL_ENRICHMENT_GROUP.inputMappings ?? []),
214+
{ inputName: 'legacyEmail', columnName: 'email' },
215+
],
216+
}
217+
const schema: TableSchema = {
218+
columns: [
219+
{ id: 'domain', name: 'Domain', type: 'string' },
220+
{
221+
id: 'email',
222+
name: 'Email',
223+
type: 'string',
224+
workflowGroupId: legacyGroup.id,
225+
},
226+
],
227+
workflowGroups: [legacyGroup],
228+
}
229+
const completed = { ...EXECUTION_STATE, status: 'completed' as const }
230+
231+
const result = deriveExecClearsForDataPatch(
232+
{ email: 'user-edited@example.com' },
233+
schema,
234+
{ [legacyGroup.id]: completed },
235+
undefined,
236+
{ domain: 'old.example', email: 'user-edited@example.com' }
237+
)
238+
239+
expect(result).toEqual({ executionsPatch: undefined, inFlightDownstreamGroups: [] })
240+
})
208241
})

0 commit comments

Comments
 (0)