Repository navigation
Commit ddab8b9
fix(studio): the flow Problems list reads the draft's publish verdict, and a blank expression says it needs one (#27826)
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wg4i9JiKjEjwtuVzd4gKy9hB)_
Fixes #27799
Clause-②: no
Metadata-protocol: none
## 维护者速读
-
改了什么:Studio「自动化」里流程的「问题」面板接上了草稿读回时服务器给出的发布判定(之前只有步骤检查器在读它);值写成表达式却留空时,节点和问题面板都改说「这个值需要一个表达式」,不再显示信封的线上格式。
- 为什么改:节点按 spec
的值槽规则报错,发布门禁也按同一规则拒绝,但问题面板只看画布结构,于是一边报错一边说「没有问题——该流程结构有效」,作者照此发布会被拒。
- 风险与回滚:只动 ui(app-shell 私有包 + i18n 两条文案);问题面板现在会多出服务器判定里的条目(包括以前就存在、但
Studio 没显示的 schema 错误),属预期;回滚即 revert 本 PR。
- 先看:`StudioDesignSurface.tsx`(把 `flowVerdict`
交给画布的那一处)、`previews/flow-problems.ts`(服务器条目的定位与文案)、`inspectors/flow-value-envelope.ts`(`isBlankExpressionRefusal`)。
- 两分钟验证:`pnpm --dir ui exec vitest run
packages/app-shell/src/views/studio-design/AutomationsPillar.problemsAgree-27799.test.tsx`,预期
3 个用例全绿。
- 需要你做的:无,席位落地。
## What changes
Measured first, on `main` at `86aaff32`, with the Studio Automations
page mounted against a server double that judges as the server does (the
save door parses `FlowSchema`; the draft read folds in the publish
gate's finding from the real `validateStackExpressions`). A
record-change flow, an Update Records node, a value `id` switched to an
expression and left blank:
- the value cell showed the spec's refusal (`AssignmentValueSchema`, run
live): "A value carrying a `dialect` key is read as an expression
envelope … Write `{ dialect: 'cel', source: '…' }`";
- the draft save was accepted (the flow parse does not run the
value-slot rule, by design: `flow-value-slot-template.ts`, "The doors
that run it"), and the draft read's `_diagnostics` carried the publish
gate's `expression-invalid` finding with the same message;
- the Problems tab read "No problems — this flow is structurally
valid.", because the page handed the served verdict to the inspectors
(objectstack#26858) and never to the canvas: `FlowPreview` got no
`diagnostics` there.
So the blank expression is a defect (the publish refuses it), and the
one judge is the spec's value-slot rule, which both the cell and the
publish gate run. The fix wires Problems to that verdict; no client-side
validator is added.
- **Problems reads the served verdict.** The Automations page hands
`flowVerdict` (the draft read's `_diagnostics`, re-read after each
autosave) to the flow preview as `diagnostics`, through
`verdictPreviewEntries` in `draftVerdict.ts`, with messages through
`translateValidationMessage` as the metadata edit page does.
- **The row names the node and the field.** The publish gate locates a
finding on a node's config value in words (`flow 'touch_account' · node
'write' (update_record) update_record field value at config.fields.id`),
not as an item path, so it cannot be placed on a node. A server row on
no element now shows the server's locator as its target instead of the
bare word "flow".
- **Business words, from the spec's own verdict.**
`isBlankExpressionRefusal` recognises the spec's refusal of a blank
expression by asking the spec once what that refusal reads
(`valueEnvelopeRefusal({ dialect: 'cel', source: '' })`), never by
restating the rule. The value cell and the Problems row both say "This
value needs an expression. Write one, or switch the value back to text."
(zh: 「这个值需要一个表达式。请填写表达式,或把这个值切回文本。」). Every other refusal shows as
before.
## Tests
- New `studio-design/AutomationsPillar.problemsAgree-27799.test.tsx`
(real `FlowPreview` + real `FlowInspector`, server double as above):
- one judge: for the blank value the flow parse passes and the publish
verdict's messages equal the cell's live spec refusal;
- the cell and the Problems row both show the business sentence; the
row's target names `node 'write'` and `config.fields.id`; the tab count
is 1;
- control: writing `record.id` clears the cell, and after the autosave
Problems reads "No problems" again.
- `FlowKeyValueField.valueEnvelope.test.tsx`: the blank-expression case
now expects the business sentence (the malformed-template case still
shows the spec's sentence).
## Acceptance notes
- Seam, outside this card's surface: the lint finding for a flow node's
config value carries no item path (`ExprIssue.path` is set for an edge
`condition` and an object validation's `condition`/`when` only), so
`_diagnostics` locates it by the `where` prose and the Problems row
cannot select or reveal the node. Seam: `lint:ExprIssue.path (flow node
value slots) → runtime:withPublishVerdict itemRelativeIssuePath →
renderer:flow-problems serverTarget`. With a
`flows[0].nodes[N].config.fields.KEY` path, the existing mapping places
the row on the node with no ui change. Filed by the seat as #27828
(`domain:spec`, p3).
- Studio's Problems list now also shows the draft's schema errors and
other publish findings it never showed before (the metadata edit page
already did). That is the intended reach, not a side effect.
- Row 27's suggestion half (a "Triggering record" target, the object
pre-filled, field pickers for keys) stays on #27521.
## Verification
<details><summary>Repro on main (before)</summary>
The measurement test, run on `86aaff32` before the change: cell alert =
the spec's envelope sentence; 1 save, 0 refused; served verdict `valid:
false` with the same message at the `where` locator; Problems showed the
empty-state sentence, 0 rows.
</details>
<details><summary>Ablations (each through scripts/ablation-replace.mjs,
restored to HEAD)</summary>
- `diagnostics: flowPreviewDiagnostics` ablated → 2 of 3 new cases red
(Problems stays empty).
- the Problems-row business wording ablated → 1 red.
- the value-cell business wording ablated → 2 red (the new case and the
updated `valueEnvelope` case).
</details>
<details><summary>Local runs</summary>
All at head `7c47a855`, under `scripts/pm/os-verify-lock.sh`:
- `pnpm --filter @object-ui/app-shell run type-check` (both tsc
programs) → exit 0.
- `pnpm --dir ui exec vitest run` over
`packages/app-shell/src/views/studio-design/` plus the 91 test files
that name `FlowPreview`, `ProblemsPanel`, `flow-problems`,
`FlowKeyValueField`, `flow-value-envelope`, `draftVerdict`,
`FlowNodeConfigField` or `FlowNodeInspector` → Test Files 357 passed
(357), Tests 3097 passed (3097).
- `pnpm --dir ui exec vitest run packages/i18n/` → Test Files 90 passed
(90), Tests 1380 passed, 13 skipped.
- `pnpm check:new-line-citations` (ui) → 0 new citations, exit 0.
- Not run locally, declared to CI: the whole Test UI shards and the rest
of the lint farm.
</details>
<details><summary>Gates</summary>
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at `7c47a855` derived 34 families; each run
and recorded as `command :: exit code` before any pipe; all 34 exit 0,
including `node scripts/check-sdui-manifest.mjs` and `pnpm --dir ui exec
vitest run scripts/` (169 passed, 2 skipped files; run alone under the
lock). `--ran` reconciliation: 34 derived, 34 run, 0 NOT-MEASURED, 0
UNRUN.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CaycqDGtn6KeXgc8hp)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 165bc50 commit ddab8b9
12 files changed
Lines changed: 333 additions & 6 deletions
File tree
- .changeset
- ui/packages
- app-shell/src/views
- metadata-admin
- inspectors
- previews
- studio-design
- i18n/src/namespaces/studio
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
81 | 97 | | |
82 | 98 | | |
83 | 99 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
| 52 | + | |
52 | 53 | | |
53 | 54 | | |
54 | 55 | | |
| |||
227 | 228 | | |
228 | 229 | | |
229 | 230 | | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
230 | 237 | | |
231 | 238 | | |
232 | 239 | | |
| |||
371 | 378 | | |
372 | 379 | | |
373 | 380 | | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
374 | 385 | | |
375 | 386 | | |
376 | 387 | | |
| |||
436 | 447 | | |
437 | 448 | | |
438 | 449 | | |
439 | | - | |
| 450 | + | |
440 | 451 | | |
441 | | - | |
| 452 | + | |
442 | 453 | | |
443 | 454 | | |
444 | 455 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
119 | 120 | | |
120 | 121 | | |
121 | 122 | | |
122 | | - | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
123 | 128 | | |
124 | 129 | | |
125 | 130 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
621 | 621 | | |
622 | 622 | | |
623 | 623 | | |
| 624 | + | |
624 | 625 | | |
625 | 626 | | |
626 | 627 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
118 | 118 | | |
119 | 119 | | |
120 | 120 | | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
65 | | - | |
| 65 | + | |
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| 35 | + | |
35 | 36 | | |
36 | 37 | | |
37 | 38 | | |
| |||
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
58 | 67 | | |
59 | 68 | | |
60 | 69 | | |
| |||
269 | 278 | | |
270 | 279 | | |
271 | 280 | | |
| 281 | + | |
272 | 282 | | |
273 | 283 | | |
274 | 284 | | |
275 | | - | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
276 | 289 | | |
277 | 290 | | |
| 291 | + | |
278 | 292 | | |
279 | 293 | | |
280 | 294 | | |
| |||
0 commit comments