Repository navigation
Header lifecycle actions succeed and the contract page keeps showing the old status and the old button until a manual reload - #105
Merged
Conversation
Submit, Accept for Review, Send for Approval, Start Signing and Activate
answered 200 {"success":true} and toasted success, but the record header
kept the old stage and the old button until a manual reload. The spec
defaults `refreshAfter` to false (materialized at parse) and the record
page re-reads the record only when it is true; Terminate and Start
Renewal already set it. `transition()` now sets it for all five.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017nzWFRUo2U7evMkPdVniAn
Contributor
Author
席位核对 — ACCEPT · head
|
| check | reading |
|---|---|
| shape | draft → main, line 1 Fixes #94, no other closing keyword in the body; assignee zhuangjianguo |
| CI on the head | both Validate check-runs success on 4239466 = PR head.sha |
| scope | 1 file, src/actions/contract-lifecycle.actions.ts (+8/−0) = the claimed surface; nothing governed |
| the fix | transition() now sets refreshAfter: true on all five lifecycle buttons; Terminate / Start Renewal already did |
| premise | held: @objectstack/spec 17.7.0 defaults refreshAfter to false; the dev measured the record page re-reading the record only when it is true |
| browser (dev's readings) | before: 5/5 presses 200 {"success":true}, header stale until reload, no record GET; after: 5/5 header updates in place, each followed by GET /api/v1/data/clm_contract 200; same 9 console warnings before and after |
| forward-compat | the key is unchanged in @objectstack/spec 18.1.0 (ui/action.zod.ts:1401, z.boolean().default(false)), so the pending 18.1 upgrade does not invalidate it |
| deviation accepted | the commit trailer names the model; it is the session's required attribution line, kept |
| out of scope | the 7-per-load No such key: status predicate warnings → Acceptance notes, carrier: none (no user-visible defect measured) |
Landing: under the maintainer's merge authorization (project thread: 「pr 你审核之后可以帮我合并」).
Generated by Claude Code
This was referenced Oct 25, 2026
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.
Fixes #94
What changed
src/actions/contract-lifecycle.actions.ts:transition()now setsrefreshAfter: true. All five header status transitions use it: Submit, Accept for Review, Send for Approval, Start Signing and Activate. That is one line plus a comment, +8/-0.Mechanism (measured, card lead confirmed):
@objectstack/spec17.7.0 declaresrefreshAfter: z.boolean().default(false)(ui/action.zod.ts:1385, materialized at parse). The record page re-reads the record only when it istrue. Terminate and Start Renewal already set it, and the fivetransition()actions did not. This is the app not asking for a refresh. It is not a Console defect, so no platform issue applies. After the change,GET /api/v1/meta/actionsservesrefreshAfter: trueonsubmit_contract,accept_contract,send_for_approval,start_signingandactivate_contract.Browser readings
Setup:
pnpm demo --port 3194from the worktree, signed in as admin@objectos.ai. Before the run, the dev admin got theclm_adminandclm_legal_counselpositions (POST /api/v1/data/sys_user_position, 201 each) so it could see every gated button. Playwright drove the pre-installed Chromium. On each contract page the script read the current stage ([aria-label="Record path"] [aria-current=step]) and the visible header action buttons, pressed the action, waited 5 s and read them again, then reloaded and read them a third time.The seeded demo rows fail the state machine's own guards: no version, no legal owner, no approved legal review, no completed signature round, no
final_signedversion. The first presses answered422 INVALID_STATEfor that reason. The missing child rows were added through the data API (an uploadedsys_filefor each version), and every row below is a200press.Before (
main@449667e):6xV7nvX2HtijCn6b200 {"success":true}1EILupHlYfR5I5UA200 {"success":true}R6oj7Y7eZJT4sX76200 {"success":true}Ik_RcazGdUz3a2tz200 {"success":true}juglMfyiqvc2jdR_200 {"success":true}After (this branch, same server with the watcher's rebuild and restart):
h_0Ue-yWMqvOpLd_200 {"success":true}GET /api/v1/data/clm_contract → 2005NW-RLdRdf7QWLR3200 {"success":true}GET /api/v1/data/clm_contract → 2001EILupHlYfR5I5UA200 {"success":true}GET /api/v1/data/clm_contract → 200vdt8ulrQ9oNghIaM200 {"success":true}GET /api/v1/data/clm_contract → 200ndw0vjMF8PTBaRg2200 {"success":true}GET /api/v1/data/clm_contract → 200After the press, the header matches the post-reload header in every case. Submit lands on In Review rather than Submitted because F2's onward hop runs in the same write: the dev admin now holds a legal-counsel position, so routing assigns it.
Browser console for every successful press, before and after: no errors. The only
errorlines in either run came from the 422 fixture presses (Failed to load resource: … 422). Each page load also logs the same 9 warnings, identical before and after: 2 component-registrybare-name fallbackwarnings, plus 7[object-ui] A conditional predicate failed to evaluate (page:header action "…" visible) … No such key: status, one per header action. See the acceptance notes.Boot: both boots printed
✓ Server is readywith nodegraded capabilities, nono such tableand no plugin load failure. The warnings were author-time approval-approver notices, scheduled flows unbound by deployment policy, the seed's deferred-reference notices (the demo personas are not created), and the plain-HTTP OAuth notice. Each server was stopped by process group.Gates (worktree,
4239466, each exit code captured before any pipe)pnpm validate: exit 0pnpm lint: exit 0pnpm typecheck: exit 0pnpm lint:i18n-gate: exit 0Acceptance notes
A conditional predicate failed to evaluate (page:header action "X" visible) … [runtime] No such key: statuswarning per header action. That is 7 per load, onmainand on this branch alike. The buttons still resolve correctly once the record is loaded, as both tables show. It looks like the predicates are evaluated once before the record arrives. The cause is in the Console, this change does not touch it, and it is out of scope for this card.Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_017nzWFRUo2U7evMkPdVniAn