Skip to content

Commit c8aeb8b

Browse files
committed
fix: properly create new mrf steps
1 parent 5ca606c commit c8aeb8b

File tree

1 file changed

+80
-24
lines changed

1 file changed

+80
-24
lines changed

packages/backend/src/apps/formsg/triggers/new-submission/create-mrf-steps.ts

Lines changed: 80 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,20 @@ export async function createMrfSteps(
5656
const deletedStep = await Step.query(trx).patchAndFetchById(step.id, {
5757
deletedAt: new Date().toISOString(),
5858
})
59-
// Shift up all steps after the deleted one
59+
// Delete all steps in the reject branch
6060
await Step.query(trx)
6161
.where('flow_id', $.flow.id)
6262
.where('position', '>', deletedStep.position)
63-
.decrement('position', 1)
63+
.andWhereRaw(`steps.config->'approval'->>'stepId' = ?`, [
64+
deletedStep.id,
65+
])
66+
.delete()
6467
}
6568

66-
// we start from after the trigger step first
67-
let newStepPosition = 2
69+
let newMrfStepPositionToInsert = 2
70+
// Track all the newly added mrf step positions
71+
const newMrfSteps = []
72+
6873
// Create or update steps for each action
6974
for (let i = 0; i < actions.length; i++) {
7075
const action = actions[i]
@@ -96,29 +101,80 @@ export async function createMrfSteps(
96101
),
97102
},
98103
)
99-
newStepPosition = updatedStep.position + 1
104+
// there could be a case where it changed from an approval step to a normal steps
105+
if (!action.approvalField) {
106+
// Delete all steps in the reject branch (if any)
107+
await Step.query(trx)
108+
.where('flow_id', $.flow.id)
109+
.where('position', '>', updatedStep.position)
110+
.andWhereRaw(`steps.config->'approval'->>'stepId' = ?`, [
111+
updatedStep.id,
112+
])
113+
.delete()
114+
}
115+
newMrfStepPositionToInsert = updatedStep.position + 1
116+
continue
117+
}
118+
// Create new mrf steps after the last created mrf step (if any)
119+
const newStep = await Step.query(trx).insert({
120+
flowId: $.flow.id,
121+
type: 'action',
122+
appKey: MRF_APP_KEY,
123+
key: MRF_KEY,
124+
position: newMrfStepPositionToInsert,
125+
connectionId: updatedTriggerStep.connectionId,
126+
parameters,
127+
config: {
128+
stepName,
129+
},
130+
})
131+
newMrfSteps.push(newStep)
132+
newMrfStepPositionToInsert = newStep.position + 1
133+
}
134+
135+
/**
136+
* Handle steps after the last newly created mrf step
137+
* CAVEAT: this relies heavily on the fact that new MRF steps are always added at the end of the formsg workflow
138+
* If last created mrf step has approval field, we need to update the steps in the reject branch to point to the last created mrf step
139+
* If last created mrf step does not have approval field, we need to delete the steps in the reject branch
140+
*/
141+
if (newMrfSteps.length > 0) {
142+
// Shift down all steps after the newly added mrf steps
143+
await Step.query(trx)
144+
.where('flow_id', $.flow.id)
145+
.where('position', '>=', newMrfSteps[0].position)
146+
.andWhereNot('key', MRF_KEY)
147+
.andWhereNot('app_key', MRF_APP_KEY)
148+
.increment('position', newMrfSteps.length)
149+
const stepIdsInRejectBranch = await Step.query(trx)
150+
.select('steps.id as id')
151+
.where('flow_id', $.flow.id)
152+
.where('position', '>=', newMrfStepPositionToInsert)
153+
.andWhereRaw(`steps.config->'approval'->>'branch' = ?`, ['reject'])
154+
const finalMrfStep = newMrfSteps[newMrfSteps.length - 1]
155+
if (actions[actions.length - 1].approvalField) {
156+
await Step.query(trx)
157+
.whereIn(
158+
'steps.id',
159+
stepIdsInRejectBranch.map((step) => step.id),
160+
)
161+
.patch({
162+
config: raw(
163+
`jsonb_set(config, '{approval,stepId}', to_jsonb(?::text), true)`,
164+
finalMrfStep.id,
165+
),
166+
})
100167
} else {
101-
// Shift all steps after this position down
102168
await Step.query(trx)
103-
.where('flow_id', $.flow.id)
104-
.where('position', '>=', newStepPosition)
105-
.increment('position', 1)
106-
107-
// Create new step at the correct position
108-
const newStep = await Step.query(trx).insert({
109-
flowId: $.flow.id,
110-
type: 'action',
111-
appKey: MRF_APP_KEY,
112-
key: MRF_KEY,
113-
position: newStepPosition,
114-
connectionId: updatedTriggerStep.connectionId,
115-
parameters,
116-
config: {
117-
stepName,
118-
},
119-
})
120-
newStepPosition = newStep.position + 1
169+
.whereIn(
170+
'steps.id',
171+
stepIdsInRejectBranch.map((step) => step.id),
172+
)
173+
.delete()
121174
}
122175
}
176+
177+
// this is to fill the gaps in the step positions
178+
await Step.resetStepOrdering($.flow.id, trx)
123179
})
124180
}

0 commit comments

Comments
 (0)