Skip to content

feat(runtime): package-scoped single-item metadata resolution via ?package= (ADR-0048) - #1816

Merged
xuyushun441-sys merged 2 commits into
mainfrom
feat/adr-0048-meta-getitem-package
Jun 13, 2026
Merged

feat(runtime): package-scoped single-item metadata resolution via ?package= (ADR-0048)#1816
xuyushun441-sys merged 2 commits into
mainfrom
feat/adr-0048-meta-getitem-package

Conversation

@xuyushun441-sys

@xuyushun441-sysxuyushun441-sys commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

What

Make a single-item metadata GET (/meta/:type/:name?package=<id>) actually resolve package-scoped (prefer-local): when two installed packages ship an item of the same type/name, the requester's own package wins.

The bug this fixes

The first commit threaded ?package= into the runtime HTTP dispatcher, but the live serving path (RestAPI + ObjectQL protocol) still dropped it for cacheable types. Browser verification surfaced the real gap:

  • rest-server — the cacheable single-item GET called getMetaItemCached (ETag keyed on type+name only) and never passed packageId. So a ?package= read on a doc/page/etc. was served package-blind, and two same-named items shared one cache entry. A ?package= read now bypasses that cache and takes the disambiguating getMetaItem(type, name, packageId) path.
  • protocol.getMetaItem — forwards packageId to the sys_metadata overlay query (package_id prefer-local filter), to metadataService.get, and to registry.getItem.
  • metadata-facadeget() gained an optional currentPackageId, forwarded to registry.getItem.
  • runtime dispatcher + spec doc.zod comments (first commit).

Why it matters

Lets the doc viewer (/apps/:packageId/docs/:name) resolve one doc scoped to its app, so doc names no longer need a namespace prefix for uniqueness (the prefix becomes a recommended convention, like page/dashboard/report).

Frontend counterpart: objectui#1708.

Verification

  • Unit: package-scoped prefer-local in getMetaItem (registry + overlay paths); REST cache-bypass on ?package=. objectql 600 / rest 108 / runtime 370 green.
  • Live (real registry-level collision — two packages each shipping doc/showcase_index):
    • curl .../doc/showcase_index?package=com.example.showcase → Showcase
    • curl .../doc/showcase_index?package=com.objectstack.studio → "STUDIO VERSION"
    • Browser: /apps/<pkg>/docs/showcase_index renders each package's own doc, no console errors.

🤖 Generated with Claude Code

…ckage= (ADR-0048)
REST single-item GET /meta/:type/:name now passes its `?package=` query into
`getItem(type, name, currentPackageId)` — the package-scoped (prefer-local)
resolution added with the namespace gate. Single-item fetch was previously
context-free (only list + protocol paths were package-aware).
Enables package-scoped single-doc resolution (doc content lives only on the
single-item endpoint), so `doc` names no longer need a namespace prefix for
uniqueness — prefix demoted to a recommended convention (doc.zod comments
updated), matching page/dashboard/report.
Verified: curl `/api/v1/meta/doc/showcase_index?package=com.example.showcase`
returns the doc with content; the package param reaches getItem's 3rd arg.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercelBot commented Jun 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 13, 2026 2:46pm

Request Review

…(ADR-0048)
The prior commit threaded ?package= into the runtime dispatcher, but the live
serving path (RestAPI + ObjectQL protocol) still dropped it for cacheable types:
- rest-server: the cacheable single-item GET called getMetaItemCached (ETag
keyed on type+name only) and never passed packageId, so a ?package= read on a
doc/page/etc. was served package-blind. Now a ?package= read bypasses that
cache and takes getMetaItem(type, name, packageId).
- protocol.getMetaItem: forward packageId to the sys_metadata overlay query
(package_id filter, prefer-local), to metadataService.get, and to
registry.getItem.
- metadata-facade: get() gained optional currentPackageId, forwarded to
registry.getItem.
Verified live: two packages (com.example.showcase, com.objectstack.studio) each
shipping doc/showcase_index now resolve to their own item via
?package=<id>, and the doc viewer route /apps/:packageId/docs/:name renders the
correct per-package content in the browser.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@xuyushun441-sys
xuyushun441-sys merged commit 0856476 into mainJun 13, 2026
12 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the feat/adr-0048-meta-getitem-package branch June 13, 2026 14:53
os-zhuang added a commit to objectstack-ai/objectui that referenced this pull request Jun 14, 2026
…x optional) (#1701)
DocPage now passes the route's package (`/apps/:appName/docs/:name`, where
:appName is the package id) to `meta.getItem('doc', name, { packageId })`. The
client SDK already sends `?package=`; the framework REST endpoint now honors it
(objectstack-ai/objectstack#1816), resolving the single doc package-scoped
(prefer-local) — so doc names no longer need a namespace prefix for uniqueness.
Legacy top-level /docs/:name (no :appName) stays context-free.
Browser-verified: /apps/com.example.showcase/docs/showcase_index issues
GET …/meta/doc/showcase_index?package=com.example.showcase → 200 and renders.
Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:systemsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@xuyushun441-sys@os-zhuang