Commit 6937572
* fix(approvals): decision outputs reach both decision surfaces (#2955)
An approval node's `decisionOutputs` (framework#3447 P2) never made it to the
approver on either Console surface, though the server has shipped the typed
declaration on the request row all along.
The Approval Center DID synthesize a typed picker per declared output
(#2831), but spelled the picker target `referenceTo`. Every collected param
passes through `resolveActionParams()` first, and its inline branch rebuilds
the param from a fixed key list, reading the target from `reference` — so the
target was dropped and `paramToField()` degraded the targetless picker to a
plain text input labelled "<label> 的记录 ID". `user` outputs were unaffected
(that widget needs no target); `department`/`position`/`team` were all broken.
The record header collected nothing at all: its Approve/Reject shipped their
inputs under `collectParams`, a key nothing reads (ActionRunner collects from
`actionParams`). No dialog had opened there since ADR-0019 — the comment was
silently dropped on every record-page decision, and a node declaring
`decisionOutputs` resumed the flow with `vars.<node>.<key>` missing, so the
next node's `expression` approver faulted or fell through to
`onEmptyApprovers` with no hint to anyone.
The widget mapping now lives in `utils/decisionOutputParams` so the two
surfaces cannot drift again; the header collects through `actionParams`, folds
`outputs.<key>` into the decide body, and its comment box is a real textarea
(the resolver drops `multiline`). Tests pin the round trip through param
resolution — the stage that actually broke — not just the emitted shape.
Verified end to end against the app-showcase runtime: an approval node
declaring a `position`-typed multi-select renders a sys_position picker in
both the Approval Center drawer and the record header, and deciding from the
record page carries the outputs through to `vars.*` — the co-sign node's
`expression` approver resolved to the user picked in the dialog.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(approvals): block a decision on a required output (#2955)
The platform half of this issue gives `decisionOutputs` a `required` flag: the
server rejects an approve that carries no value for one, before any write, so
the run can never resume past the node with the key a downstream `expression`
approver reads still missing.
The console mirrors it where the approver actually is. A required output is
marked required on the param it synthesizes, so the dialog flags the empty
field and refuses Confirm instead of sending a decision the server will 400.
APPROVE only, matching the server: a reject leaves down the reject edge where
nothing reads the outputs, so the reject dialog offers the same fields without
blocking on them — the two dialogs now differ in exactly that flag. Both
decision surfaces get it from the one shared helper, and a backend that
predates the field requires nothing, which is the behaviour of the previous
commit unchanged.
Verified against the showcase runtime (its dynamic-approval flow declares the
flag): the record header's Approve refuses with "Next Reviewers 为必填项" and
sends no request, its Reject offers the field unmarked, the Approval Center
drawer agrees on both, and a filled approve routes the co-sign node to the
picked user.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent e651c93 commit 6937572
9 files changed
Lines changed: 865 additions & 92 deletions
File tree
- .changeset
- packages/app-shell/src
- hooks
- utils
- views
- __tests__
Lines changed: 53 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
Lines changed: 106 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
44 | 45 | | |
45 | 46 | | |
46 | 47 | | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
47 | 61 | | |
48 | 62 | | |
49 | 63 | | |
| |||
71 | 85 | | |
72 | 86 | | |
73 | 87 | | |
74 | | - | |
75 | | - | |
| 88 | + | |
| 89 | + | |
76 | 90 | | |
77 | 91 | | |
78 | 92 | | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
79 | 102 | | |
80 | 103 | | |
81 | 104 | | |
| |||
162 | 185 | | |
163 | 186 | | |
164 | 187 | | |
165 | | - | |
| 188 | + | |
166 | 189 | | |
| 190 | + | |
167 | 191 | | |
168 | 192 | | |
169 | 193 | | |
170 | 194 | | |
171 | 195 | | |
172 | 196 | | |
173 | 197 | | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
174 | 203 | | |
175 | 204 | | |
176 | 205 | | |
| |||
180 | 209 | | |
181 | 210 | | |
182 | 211 | | |
183 | | - | |
184 | | - | |
| 212 | + | |
| 213 | + | |
185 | 214 | | |
186 | 215 | | |
187 | 216 | | |
| |||
0 commit comments