Repository navigation
fix(app-shell): clearing the flow designer's cron no longer leaves a schedule block with no cadence - #31412
Merged
Conversation
…ule block left with no cadence Co-Authored-By: Claude <noreply@anthropic.com>
…no cadence, untyped { timezone } included
Co-Authored-By: Claude <noreply@anthropic.com>
… cadence inspector test Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
Author
|
domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr 席位核对 · ACCEPT · 2026-11-08T06:45Z · head
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Leehom · project thread
Fixes #31383
Clause-②: no
Metadata-protocol: none
维护者速读
config.schedule已经没有任何周期(只剩type、timezone之类),现在整块删掉,不再写出{ type: 'cron' }或{ type: 'cron', timezone }。无类型的{ expression, timezone }清空后原来会剩{ timezone },同一个缺陷,一并处理。输入新的 cron 时行为不变:带类型的块照旧保留type和timezone。FlowSchema以 422 拒绝,而这个形状正是设计器自己写出来的。@object-ui/app-shell里scheduleWithExpression一个函数的「清空」分支;不改 spec、不改服务端、不加 i18n 文案。回滚即 revert。ui/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts中scheduleWithExpression的清空分支(return normalizeScheduleCadence(next) === null ? undefined : next;),以及两个测试文件末尾新增的objectstack#31383describe。pnpm --dir ui exec vitest run packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.scheduleCadence-12779.test.ts packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.scheduleCadence-12779.test.tsx,预期 2 个文件 68 个用例全绿。What changes
scheduleWithExpression(flow-node-config.ts,@object-ui/app-shell). The clearing arm used to deleteexpressionandcronand keep whatever else the object held, collapsing only an object left empty. It now returnsundefinedwhenever the remaining object resolves to no cadence throughnormalizeScheduleCadence, the designer's branch-for-branch mirror of the engine'snormalizeSchedule. So:{ type: 'cron', expression }or{ type: 'cron', expression, timezone }stores noconfig.schedule;{ expression, timezone }stores noconfig.scheduleeither (it used to leave{ timezone });{ expression }stores nothing, as before;{ expression, intervalMs }leaves{ intervalMs }, which the engine binds as an interval, as before.The set arm is unchanged. Its tail is rewritten without the
else, because the set arm always writesexpression, so the old empty-object check could only fire on the clearing arm. The function's doc comment and the field's comment say what clearing now stores.config.schedule.FlowNodeInspector.tsxroutes every commit on the Cron schedule path throughscheduleWithExpression(line 552); the otherschedule*helpers in the file (normalizeScheduleCadence,scheduleCadenceOf,scheduleFieldValue,readOnlyScheduleCadence) only read. The Advanced JSON box writes whatever the author types and is not a designer-produced shape..changeset/31383-flow-designer-cleared-cron-drops-typed-schedule.md:@object-ui/app-shellpatch, both declaration lines.Tests
flow-node-config.scheduleCadence-12779.test.ts: the old assertion that pinned the defect (clearing{ type: 'cron', expression, timezone: 'UTC' }returned{ type: 'cron', timezone: 'UTC' }) is removed from the existing clearing case, and a new describe for objectstack#31383 adds 11 cases:undefined, a typed{ cron }with a timezone, a typed cron that already had no cadence, anintervaltype that carried only an expression, and an unknown type beside an expression: each returnsundefined;{ expression, timezone }returnsundefined;{ expression }still clears toundefined; a cron typed over{ type: 'cron', expression, timezone }or{ type: 'cron', timezone }keepstypeandtimezone; clearing{ expression, intervalMs }keeps the interval the engine then binds.FlowNodeInspector.scheduleCadence-12779.test.tsx(rendered, through the real Cron schedule input andfireEvent.change): clearing the box on a typed cron, and on a typed cron with a timezone, leaves the start node'sconfigwith noschedulekey and itsobjectNamekept, and the box reads empty. CONTROL: clearing an untyped{ expression }stores no schedule, as before. The file now imports@objectstack/lintat module top, as its sibling inspector tests do, because the inspector reaches it through function-bodyimport()s andcheck:test-source-aliasasks an edited test file to pay that load at collection.scripts/ablation-replace.mjs: the clearing arm's return put back to the oldObject.keys(next).length === 0 ? undefined : next(anchor 1 to 0, blobaa3d830dto91bc6d94). Result: 10 failed, 58 passed (68): the 8 new table cases and the 2 rendered typed cases red; every CONTROL green. Restored: blob equal to HEAD (aa3d830d),git diff HEADempty. Both tests importflow-node-config.tsfrom source by relative path, so no build sat between the mutation and the run.Acceptance notes
{ timezone }leftover is fixed in place. The grade record says the untyped form already collapses; that holds for{ expression }but not for{ expression, timezone }, which left{ timezone }. The engine binds nothing from it, and PR fix(spec)!: refuse a start-node filter beside timeRelative and a schedule the readers cannot use #31376'sflowStartScheduleReadsNothingrefuses an untyped object it reads nothing from, so it is the same defect in the same function. All four conditions of the bounded in-place fix hold: same defect class, a mechanical fix pinned here, the file is inside this claim's surface, and no new gate family. Named here so the seat can rule it out if it prefers the narrower reading.FlowSchemarefusals. The shapes this PR stops writing are the ones its review named: a typed cron with noexpression, which the publishedScheduleSchemaalready refuses onmain.Clause-②: no,Metadata-protocol: none, as the claim opened.Verification
Run on head
3251f97c(baseorigin/main03533d2c).Build, tests and lint
pnpm --workspace-concurrency=2 --filter '@objectstack/spec...' --filter '@objectstack/formula...' --filter '@objectstack/client...' --filter '@objectstack/lint...' --filter '@objectstack/sdui-parser...' build: VERDICT command-exit 0.pnpm --dir ui exec vitest run --maxWorkers=2on the two touched test files: Test Files 2 passed (2), Tests 68 passed (68).scheduleWithExpression's module or rendersFlowNodeInspector(inspectors/FlowNodeInspector*andinspectors/flow-node-config*, 39 files): Test Files 39 passed (39), Tests 667 passed, 1 skipped.pnpm --dir ui run check:new-line-citations: 0 new citations, exit 0.@object-ui/app-shelltype-checkwas not run locally (it needs every@object-ui/*dist built);check:type-check-debtbelow exits 0, and CI's type-check lane runs the package.Derived gates (36)
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 36 families on this diff. On head3251f97call 36 exited 0, among thempnpm --dir ui exec vitest run scripts/andpnpm check:type-check-debt.--ranreconciliation with exit codes recorded: 36 derived, 36 run, 0 NOT-MEASURED, 0 UNRUN. The first round, on93b35e72, had one red:check:test-source-aliasasked the edited rendered test to load@objectstack/lintat module top;3251f97cadds that import, and the whole list was re-run. Changed lines: 106, under the 3,000 threshold.Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_01FEkQ5oAnL2z711MLVm7ZnB