feat(studio): render the runtime authoring gate's advisory findings after a save - #4236
Merged
Merged
Conversation
…fter a save The gate's advisories ride a 200 — the save succeeded, the row persisted — and objectui discarded them client-side: `MetadataClient.save` parsed the response body, returned it as an opaque `T`, and every call site awaited it for its side effect and dropped the value. objectstack#7435 put them on the wire; this renders them. `MetadataClient` gains an `onSaveAdvisory` sink, invoked after a save whose response carried a non-empty `advisories[]`. The console wires it in `useMetadataClient` — the one hook every app-shell write path takes its client from — so a single wiring covers ResourceEditPage, StudioDesignSurface, EmbeddedItemEditor, DatasourceResourcePage and ObjectHooksPanel rather than a toast copied into twenty call sites. The finding shape is re-exported from `@objectstack/spec` (`RuntimeAuthoringIssue`) rather than restated, so it cannot fork from the 422 `issues[]` it shares a declaration with. The affordance is the warning tier and says "Saved" first: a successful save that reads as a failure is the defect this surface must not ship. `message` and `hint` are server prose and render verbatim; only the frame is translated. Coverage is stated honestly and pinned: drafts are never gated (the framework returns at its D1 early-return before running a rule), so Studio's designer — which saves as draft on every edit — surfaces nothing today, and the publish door returns no advisories until objectstack#7294. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
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 #4133
The gate's advisories ride a 200 — the save succeeded, the row persisted, the version bumped — and objectui discarded them one layer further out than the server used to:
MetadataClient.saveparsed the response body, returned it as an opaqueT, and every call site awaited it for its side effect and dropped the value. objectstack#7435 (89d7b35a7) put them on the wire; this renders them.Premise check
Verified against the installed rc.6 dist rather than assumed (a runtime
safeParse, not a type read):rulesRunis absent from the response and nothing here expects it.The call-site map
Every app-shell write path takes its client from
useMetadataClient, so that hook — not the ~20client.save(...)call sites — is where this lifts. Measured, with the save mode each site uses:ResourceEditPage.tsx:1100— the main authoring editordraftStudioDesignSurface.tsx— 8 sites, all pillarsdraftObjectHooksPanel.tsx,PackageOwdOverviewPanel.tsxdraftviews/runtime-metadata-persistence.tsdraftEmbeddedItemEditor.tsx:102datasource/DatasourceResourcePage.tsx:427plugin-designerobject / field / app pagesMetadataClientConfig)MetadataProvider's client is read-only and never receives one, so it is not wired.Flow coverage — stated honestly, and pinned
A draft-then-publish flow surfaces nothing today, at both of its doors, for two different reasons — and the first is not the one the card assumed:
metadata-protocol/src/runtime-authoring-gate.ts:388:PublishMetaItemResponseSchemacarries noadvisoriesfield until objectstack#7294.Since Studio's designer saves as draft on every edit, that is the whole designer.
a draft save carries no findings — the gate never ran (D1)is the control test asserting the publish path is unchanged.Shape
Mirrors
ObjectStackAdapter.onWriteWarning(#3431/#3455) — the repo's existing seam for exactly this problem: a successful write whose response carries something the author must be told, emitted as an event so the data layer never imports a toaster. Rendering mirrorswriteWarningToast.ts(pure builder, caller-owned sink) and the 10s multi-finding toast ofpreview/usePublishAllDrafts.ts.Warning tier, never error — the title says "Saved" first, because a successful save that reads as a failure is the defect this surface must not ship. Each finding renders
rule+message+hint, withwhereas secondary context;pathis a machine pointer and is omitted.message/hintare server prose, rendered verbatim — only the frame is translated (console.saveAdvisoryTitle, all ten packs). The finding type is re-exported from@objectstack/spec(RuntimeAuthoringIssue), not restated, so it cannot fork from the 422issues[]it shares a declaration with.Malformed findings are dropped rather than printed as blanks, and a throwing renderer cannot turn a committed save into an error.
Reverse verification
Direction predicted before running: removing the emit restores "parse and discard", so the pins asserting an event arrives go red and the absence-asserting ones cannot see it.
Measured, exactly as predicted — 5 red / 20 green:
Worth recording:
saveAdvisoryToast.test.tsstayed fully green through the revert. It exercises the pure builder, not the wiring — those tests alone would not catch this regression, which is what the data-layer emit pins carry. The clone pins are there becauseuseMetadataClientroutes every console client throughwithEnvironment; dropping the sink there would have disabled the channel silently.Tests
Pre-existing reds, confirmed not mine
Both comparison-worktreed against clean
origin/main(6314e87f2):check:spec-symbols— identical failure set on clean main (5 symbols in@object-ui/types, incl.complex.zod.ts). MyRuntimeAuthoringIssuere-export passes the gate.data-objectstacktype-check —spec-symbol-batch6.test.ts(208)reproduces with my changes fully reverted viagit checkout origin/main --. Cause: rc.6 added a thirdDroppedFieldsEvent.reasonmember (primary_key) and the typetest pins two.app-shelltype-check — theresolveActionParams.test.tsreds. No error in any file this PR touches.All belong to the #4169 rc.6 train / PR #4208, not to this change.
Generated by Claude Code