Resolve a decision with a written-in option
What does this MR do and why?
Resolve a decision with a written-in option
An open decision could only be resolved by picking existing options or rejecting them all, so a user's own answer had no structured home. The write is shared with the update service, whose collapse already records a written-in option as the single selected one.
Related to #631044 (closed)
FE integration notes
The workItemDecisionResolve mutation now accepts a written-in answer via selectedOptionContent. This should be used when resolving open questions manually with a custom, user-inputted option, whether there are existing options or not.
The resolutionRationale here is optional, as with other resolution flows involving options.
Example payload:
{
"input": {
"id": "gid://gitlab/WorkItems::Decision/42",
"selectedOptionContent": "Use SQLite for the prototype",
"resolutionRationale": "Fastest to set up"
}
}Note - once the decision is resolved this way, this will become the sole selected option.
DB review notes
No migrations. This MR adds one new SQL statement shape; every other statement on the changed paths already has an approved plan in a previous MR.
Files for DB review
| File | Why |
|---|---|
ee/app/models/work_items/decision.rb |
New #write_in_option!: the bulk update_all below, followed by an option insert, inside its own transaction |
ee/app/services/work_items/decisions/resolve_service.rb |
New caller of #write_in_option! on the resolve path |
ee/app/services/work_items/decisions/update_service.rb |
The MR 6 collapse now calls #write_in_option!, so its deselect statement changes shape (see below) |
Queries
Deselect the selected options — ee/app/models/work_items/decision.rb:94
Emitted by options.where(selected: true).update_all(selected: false, updated_at: Time.current).
Note: The deselect from !257464 (merged) moved into Decision#write_in_option! so the resolve path can reuse it. Since the model has no loaded option list, it filters by selected = TRUE instead of an explicit id list, which is why the statement appears as a new shape here; the rows it touches are unchanged, and on the resolve path it matches nothing.
UPDATE "work_item_decision_options" SET "selected" = FALSE, "updated_at" = '2026-10-01 23:27:31.962902' WHERE "work_item_decision_options"."work_item_decision_id" = 31381 AND "work_item_decision_options"."selected" = TRUEPlan on a resolved decision with two selected options out of three (write-in edit of comma-separated UX list, creating new custom option): https://explain.depesz.com/s/1oWO
Same statement on an open decision with three unselected options (resolve write-in, creating new custom option): https://explain.depesz.com/s/WPvu
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Related to #631044 (closed)