Skip to content

Commit fad8e49

Browse files
authored
docs(spec): retire stale renderViaSchema comment + browser-verify ADR-0085 detail shapes (#2548) (#3019)
Follow-up to objectui#2546 (ADR-0085 PR4): rewrite the stale renderViaSchema forward-reference comment into a completed-state note, and land the deferred real-backend browser verification of the four detail-page shapes (grouped / ungrouped / stageField:false / related-heavy) as a dogfood audit note. Comment + docs only; no type/runtime change.
1 parent c435e29 commit fad8e49

3 files changed

Lines changed: 120 additions & 1 deletion

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
docs(spec): retire the stale `renderViaSchema` forward-reference now that objectui#2546 landed (ADR-0085 PR4 follow-up, #2548)
6+
7+
The `ObjectSchema` source comment forward-referenced `renderViaSchema`
8+
retiring "together with the legacy monolith render path" — a promise about
9+
work that had not yet shipped. That path, and the `detail.renderViaSchema`
10+
kill-switch that was its only steering wheel, were removed in objectui#2546
11+
(ADR-0085 PR4). The comment now records the completed state with a breadcrumb
12+
to that PR instead of a forward reference, closing the cleanup #2546 flagged.
13+
14+
Comment-only change; no type, schema, or runtime behavior is affected.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Audit: ADR-0085 PR4 — real-backend browser verification of the four detail-page shapes
2+
3+
**Date**: 2026-07-16 · **Scope**: objectui `RecordDetailView` rendering after the
4+
legacy monolith detail renderer + `renderViaSchema` kill-switch were removed
5+
(objectui#2546, ADR-0085 PR4). **Method**: drive the running `app-showcase`
6+
backend + the objectui Console (post-#2546 source) in a real headless browser.
7+
**Tracked as**: #2548 (the verification objectui#2546 deferred: "Exercising the
8+
four detail-page shapes … against real data needs a running `@objectstack`
9+
backend, which the CI/agent environment doesn't have. Deferred to #2548 with a
10+
repro runbook.")
11+
12+
## Why this is a separate pass
13+
14+
objectui#2546 deleted the non-schema-driven `DetailView` monolith branch, so
15+
`RecordDetailView` now has exactly **one** path: an authored
16+
`PageSchema(pageType='record')` when assigned, else `buildDefaultPageSchema()`
17+
synthesis — both rendered through `<SchemaRenderer>`. Unit + DOM suites and the
18+
served-metadata proof (`packages/dogfood/test/semantic-roles.dogfood.test.ts`)
19+
cover parse and serialization, but neither renders a page in a browser against a
20+
live backend. This pass closes that gap for the four shapes the PR called out.
21+
22+
## Fixtures (all in `examples/app-showcase`)
23+
24+
| Shape | Object / record | Role posture |
25+
|---|---|---|
26+
| **grouped** | `showcase_semantic_zoo` | `fieldGroups: [basics, money(collapsed)]`, `stageField: 'status'`, `highlightFields: [name,status,amount]` |
27+
| **ungrouped** | `showcase_account` (Details tab) | no `fieldGroups` → flat auto-columns |
28+
| **stageField:false** | `showcase_semantic_zoo_legacy` | `stageField: false` with a `status`-named field (must NOT get a stepper) |
29+
| **related-heavy** | `showcase_account` = "Contoso" | inbound lookups from contact / invoice / project / field_zoo |
30+
31+
`showcase_semantic_zoo{,_legacy}` are the ADR-0085 runtime fixtures; the
32+
`showcase_account` seed provides the ungrouped + related-heavy record (Contoso:
33+
2 contacts, 2 invoices, 2 projects).
34+
35+
## Repro runbook
36+
37+
```bash
38+
# 1. Backend — showcase on a private port + DB, seeded dev admin.
39+
pnpm --filter @objectstack/example-showcase... build # or: pnpm build
40+
node packages/cli/bin/run.js dev \
41+
-p 4600 -d file:/tmp/showcase-verify.db --seed-admin --compile \
42+
--cwd examples/app-showcase
43+
curl -s localhost:4600/api/v1/health # -> {"status":"ok"}
44+
45+
# 2. Console — objectui source (post-#2546) pointed at the backend. CORS is
46+
# enabled in dev, so the cross-origin :5180 -> :4600 calls are allowed.
47+
cd ../objectui
48+
VITE_SERVER_URL=http://localhost:4600 pnpm --filter @object-ui/console dev # :5180
49+
50+
# 3. Auth + fixtures (better-auth Bearer). Sign in, grab the set-auth-token
51+
# header, POST the two semantic-zoo records (not seeded), then drive the
52+
# detail URLs with Playwright:
53+
# /apps/showcase_app/<object>/record/<id>
54+
# inject localStorage['auth-session-token'] = <token> before app boot.
55+
```
56+
57+
The exact Playwright driver + JSON report used for this pass are attached to the
58+
#2548 PR discussion.
59+
60+
## Results — all four shapes render correctly through the schema-only path
61+
62+
| Shape | Observed | Verdict |
63+
|---|---|---|
64+
| **grouped** (`Zoo Grouped Alpha`) | Highlight strip `name / Active / 4,200` (= `highlightFields`); `record:path` stepper **Draft → Active → Done** (from `stageField:'status'`); ungrouped `notes` in the "More details" bucket. | ✅ renders |
65+
| **ungrouped** (Contoso · Details) | Flat two-column field layout (owner / website / HQ / tax / billing) with the "Show 4 empty fields" toggle — no section headers. | ✅ renders |
66+
| **stageField:false** (`Zoo Legacy Beta`) | Highlight strip `name / 99`; the `status` field renders as an ordinary **"STATUS: Green"** field with **no `record:path` stepper** (`[aria-label="Record path"]` absent). The `false` correctly suppresses the heuristic. | ✅ suppressed |
67+
| **related-heavy** (Contoso) | Tab strip **Details · Invoices (2) · Projects (2) · Related (2)** — primary related lists promoted to their own tabs, the rest collapsed into "Related" (ADR-0085 prominence rule); lists lazy-fetch on tab show. | ✅ renders |
68+
69+
`hasRecordPath` matched the expectation for every case (true for grouped +
70+
related-heavy, **false** for stageField:false). No page-render errors, no error
71+
boundaries, no missing-data states.
72+
73+
### Note on the "grouped" fixture
74+
75+
`showcase_semantic_zoo`'s grouped fields (`status` ∈ basics, `amount` ∈ money)
76+
are *also* its `highlightFields`, so they surface in the highlight strip and the
77+
`record:details` derivation correctly drops the now-empty Basics/Money groups,
78+
leaving only the ungrouped `notes` ("More details"). This is the intended
79+
"one curated list, every surface" behavior — the same reason Contoso's
80+
highlighted `status/industry/revenue` do not repeat in its Details body. The
81+
`fieldGroups → section` derivation itself (declared order, collapse, trailing
82+
untitled bucket) is separately proven over the served pipeline in
83+
`semantic-roles.dogfood.test.ts`.
84+
85+
## Out-of-scope observations (not defects in the detail path)
86+
87+
- `502 /api/v1/runtime/config` and `502 /api/v1/dev/metadata-events` are
88+
**same-origin** requests the Console makes to its own origin (`:5180`); in the
89+
split-origin verify harness the Vite server has nothing there. `initRuntimeConfig`
90+
absorbs the failure by design and the app boots + renders regardless. Not seen
91+
in the normal same-origin (`--ui` / vendored console) deployment.
92+
- `401 /api/v1/approvals/requests?…` (the header approvals badge) is a peripheral
93+
poll unrelated to record rendering; the detail pages loaded their data fine.
94+
Left for separate triage.
95+
96+
## Conclusion
97+
98+
The removal of the legacy monolith renderer (objectui#2546) leaves all four
99+
detail-page shapes rendering correctly through the single `SchemaRenderer` /
100+
`buildDefaultPageSchema` path against a real `@objectstack` backend. **No
101+
regressions found; no objectui follow-up required.** The framework-side cleanup
102+
#2546 flagged (the stale `renderViaSchema` source comment) ships alongside this
103+
note.

packages/spec/src/data/object.zod.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,9 @@ const ObjectSchemaBase = z.object({
970970
// control is an assigned Page. The passthrough block bred silently-inert
971971
// keys (9 read by renderers vs 3 typed; the typed `hideReferenceRail` was
972972
// itself a no-op for spec authors) — see the ADR for the full inventory.
973-
// `renderViaSchema` retires together with the legacy monolith render path.
973+
// `renderViaSchema` — the block's last-surviving key, kept only as the
974+
// legacy monolith detail renderer's kill-switch — retired with that
975+
// renderer in objectui#2546 (ADR-0085 PR4).
974976

975977
/**
976978
* Object Actions

0 commit comments

Comments
 (0)